@productmaker/mcp 12.1.0 → 12.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/http.js +1290 -869
- package/dist/stdio.js +1349 -829
- package/dist/ui/task-results-app.html +461 -0
- package/package.json +2 -2
package/dist/http.js
CHANGED
|
@@ -5326,6 +5326,7 @@ var ImageCreativeArchetype = z24.enum([
|
|
|
5326
5326
|
"problem_solution",
|
|
5327
5327
|
"lifestyle_identity"
|
|
5328
5328
|
]);
|
|
5329
|
+
var MAX_IMAGE_CREATIVE_VARIANTS = 6;
|
|
5329
5330
|
var ImageCreativeVisualTreatment = z24.enum([
|
|
5330
5331
|
"performance_product_ad",
|
|
5331
5332
|
"premium_dtc_carousel"
|
|
@@ -23784,14 +23785,37 @@ var WebsiteCaptureResearchSchema = z116.object({
|
|
|
23784
23785
|
});
|
|
23785
23786
|
|
|
23786
23787
|
// ../../packages/types/src/demo-mode.ts
|
|
23788
|
+
import { z as z118 } from "zod";
|
|
23789
|
+
|
|
23790
|
+
// ../../packages/types/src/demo-mode-service-page-assets.ts
|
|
23787
23791
|
import { z as z117 } from "zod";
|
|
23792
|
+
var DemoServicePageAssetSourceSchema = z117.object({
|
|
23793
|
+
pageId: z117.string().uuid(),
|
|
23794
|
+
ownerId: z117.string().min(1),
|
|
23795
|
+
assets: z117.array(z117.object({
|
|
23796
|
+
id: z117.string().uuid(),
|
|
23797
|
+
storageKey: z117.string().min(1).max(1024),
|
|
23798
|
+
mediaType: z117.enum([
|
|
23799
|
+
"image/webp",
|
|
23800
|
+
"video/mp4"
|
|
23801
|
+
]),
|
|
23802
|
+
byteSize: z117.number().int().positive().max(32 * 1024 * 1024),
|
|
23803
|
+
width: z117.number().int().positive().max(1920),
|
|
23804
|
+
height: z117.number().int().positive().max(1920),
|
|
23805
|
+
contentHash: z117.string().regex(/^[a-f0-9]{64}$/i),
|
|
23806
|
+
sourceKind: ServicePageSourceKindSchema,
|
|
23807
|
+
approvedAt: z117.string().datetime()
|
|
23808
|
+
}).strict()).max(24)
|
|
23809
|
+
}).strict();
|
|
23810
|
+
|
|
23811
|
+
// ../../packages/types/src/demo-mode.ts
|
|
23788
23812
|
var DEMO_MODE_FLOWS = [
|
|
23789
23813
|
"brand",
|
|
23790
23814
|
"servicePage",
|
|
23791
23815
|
"motion",
|
|
23792
23816
|
"image"
|
|
23793
23817
|
];
|
|
23794
|
-
var DemoModeFlowSchema =
|
|
23818
|
+
var DemoModeFlowSchema = z118.enum(DEMO_MODE_FLOWS);
|
|
23795
23819
|
var DEMO_MODE_STEPS = [
|
|
23796
23820
|
"running",
|
|
23797
23821
|
"research",
|
|
@@ -23804,27 +23828,30 @@ var DEMO_MODE_STEPS = [
|
|
|
23804
23828
|
"final",
|
|
23805
23829
|
"watchdog"
|
|
23806
23830
|
];
|
|
23807
|
-
var DemoModeStepSchema =
|
|
23831
|
+
var DemoModeStepSchema = z118.enum(DEMO_MODE_STEPS);
|
|
23808
23832
|
var DEMO_MODE_WAIT_SECONDS = {
|
|
23809
23833
|
min: 30,
|
|
23810
23834
|
max: 450,
|
|
23811
23835
|
default: 150
|
|
23812
23836
|
};
|
|
23813
|
-
var centsSchema =
|
|
23814
|
-
var emailSchema =
|
|
23815
|
-
var
|
|
23816
|
-
|
|
23817
|
-
|
|
23818
|
-
|
|
23819
|
-
|
|
23820
|
-
|
|
23821
|
-
|
|
23822
|
-
|
|
23823
|
-
|
|
23837
|
+
var centsSchema = z118.number().int().min(0).max(1e5);
|
|
23838
|
+
var emailSchema = z118.string().trim().toLowerCase().email();
|
|
23839
|
+
var optionalTemplateId = z118.preprocess((value) => value === "" ? void 0 : value, z118.string().uuid().optional());
|
|
23840
|
+
var DemoModeTemplatesSchema = z118.object({
|
|
23841
|
+
brandId: z118.string().uuid(),
|
|
23842
|
+
servicePageId: z118.string().uuid(),
|
|
23843
|
+
motionTaskId: z118.string().uuid(),
|
|
23844
|
+
motionVariantTaskId: optionalTemplateId,
|
|
23845
|
+
motionThirdTaskId: optionalTemplateId,
|
|
23846
|
+
imageTaskId: z118.string().uuid()
|
|
23847
|
+
});
|
|
23848
|
+
var DemoModeEditableSchema = z118.object({
|
|
23849
|
+
enabled: z118.boolean(),
|
|
23850
|
+
emails: z118.array(emailSchema).max(50).transform((list) => [
|
|
23824
23851
|
...new Set(list)
|
|
23825
23852
|
]),
|
|
23826
|
-
waitSeconds:
|
|
23827
|
-
chargeCents:
|
|
23853
|
+
waitSeconds: z118.number().int().min(DEMO_MODE_WAIT_SECONDS.min).max(DEMO_MODE_WAIT_SECONDS.max),
|
|
23854
|
+
chargeCents: z118.object({
|
|
23828
23855
|
brand: centsSchema,
|
|
23829
23856
|
servicePage: centsSchema,
|
|
23830
23857
|
motion: centsSchema,
|
|
@@ -23832,73 +23859,77 @@ var DemoModeEditableSchema = z117.object({
|
|
|
23832
23859
|
}),
|
|
23833
23860
|
templates: DemoModeTemplatesSchema
|
|
23834
23861
|
});
|
|
23835
|
-
var nullableString =
|
|
23836
|
-
var DemoModeSnapshotSchema =
|
|
23837
|
-
brand:
|
|
23862
|
+
var nullableString = z118.string().nullable();
|
|
23863
|
+
var DemoModeSnapshotSchema = z118.object({
|
|
23864
|
+
brand: z118.object({
|
|
23838
23865
|
/** Columnas de identidad de `Brand` listas para un `update` (sin id/userId/slug/estado/fechas). */
|
|
23839
|
-
identity:
|
|
23840
|
-
productSamples:
|
|
23841
|
-
name:
|
|
23842
|
-
priceCents:
|
|
23866
|
+
identity: z118.record(z118.unknown()),
|
|
23867
|
+
productSamples: z118.array(z118.object({
|
|
23868
|
+
name: z118.string(),
|
|
23869
|
+
priceCents: z118.number().int().nullable(),
|
|
23843
23870
|
currency: nullableString,
|
|
23844
|
-
imageKey:
|
|
23871
|
+
imageKey: z118.string(),
|
|
23845
23872
|
productUrl: nullableString,
|
|
23846
|
-
position:
|
|
23873
|
+
position: z118.number().int()
|
|
23847
23874
|
})),
|
|
23848
|
-
personas:
|
|
23849
|
-
name:
|
|
23875
|
+
personas: z118.array(z118.object({
|
|
23876
|
+
name: z118.string(),
|
|
23850
23877
|
demographics: nullableString,
|
|
23851
23878
|
painPoints: nullableString,
|
|
23852
23879
|
motivations: nullableString,
|
|
23853
23880
|
objections: nullableString,
|
|
23854
23881
|
gender: nullableString,
|
|
23855
|
-
isDefault:
|
|
23882
|
+
isDefault: z118.boolean()
|
|
23856
23883
|
}))
|
|
23857
23884
|
}),
|
|
23858
|
-
servicePage:
|
|
23859
|
-
facts:
|
|
23860
|
-
review:
|
|
23861
|
-
artifact:
|
|
23885
|
+
servicePage: z118.object({
|
|
23886
|
+
facts: z118.unknown(),
|
|
23887
|
+
review: z118.unknown(),
|
|
23888
|
+
artifact: z118.unknown(),
|
|
23889
|
+
/** Optional only for snapshots saved before page-owned demo media. */
|
|
23890
|
+
assetSource: DemoServicePageAssetSourceSchema.optional()
|
|
23862
23891
|
}),
|
|
23863
|
-
motion:
|
|
23892
|
+
motion: z118.object({
|
|
23864
23893
|
outputs: MotionGraphicsOutputsSchema,
|
|
23865
23894
|
/**
|
|
23866
23895
|
* La captura REAL de la web de la plantilla (nunca una fabricada por la
|
|
23867
23896
|
* demo). Null cuando la plantilla no tiene ninguna: la captura demo nunca
|
|
23868
23897
|
* va live, así que el servicio usa `DEMO_MODE_PLACEHOLDER_CAPTURE`.
|
|
23869
23898
|
*/
|
|
23870
|
-
capture:
|
|
23871
|
-
bundleKey:
|
|
23872
|
-
sha256:
|
|
23873
|
-
uploadBytes:
|
|
23899
|
+
capture: z118.object({
|
|
23900
|
+
bundleKey: z118.string(),
|
|
23901
|
+
sha256: z118.string(),
|
|
23902
|
+
uploadBytes: z118.number().int().nullable(),
|
|
23874
23903
|
previewKey: nullableString
|
|
23875
23904
|
}).nullable()
|
|
23876
23905
|
}),
|
|
23877
|
-
image:
|
|
23878
|
-
provider:
|
|
23879
|
-
model:
|
|
23880
|
-
prompt:
|
|
23881
|
-
imageUrl:
|
|
23882
|
-
width:
|
|
23883
|
-
height:
|
|
23906
|
+
image: z118.object({
|
|
23907
|
+
provider: z118.string(),
|
|
23908
|
+
model: z118.string(),
|
|
23909
|
+
prompt: z118.string(),
|
|
23910
|
+
imageUrl: z118.string(),
|
|
23911
|
+
width: z118.number().int(),
|
|
23912
|
+
height: z118.number().int(),
|
|
23884
23913
|
adCopy: nullableString,
|
|
23885
|
-
rawResponse:
|
|
23914
|
+
rawResponse: z118.unknown()
|
|
23886
23915
|
})
|
|
23887
23916
|
});
|
|
23888
23917
|
var DemoModeConfigSchema = DemoModeEditableSchema.extend({
|
|
23889
23918
|
snapshot: DemoModeSnapshotSchema.nullable(),
|
|
23890
|
-
snapshotAt:
|
|
23919
|
+
snapshotAt: z118.string().datetime().nullable()
|
|
23891
23920
|
});
|
|
23892
23921
|
var DemoModeAdminViewSchema = DemoModeEditableSchema.extend({
|
|
23893
23922
|
// Sin configurar, la API devuelve ids vacíos ("" no es uuid): la vista los
|
|
23894
23923
|
// admite; el PUT sí exige uuid (`DemoModeEditableSchema`).
|
|
23895
|
-
templates:
|
|
23896
|
-
brandId:
|
|
23897
|
-
servicePageId:
|
|
23898
|
-
motionTaskId:
|
|
23899
|
-
|
|
23924
|
+
templates: z118.object({
|
|
23925
|
+
brandId: z118.string(),
|
|
23926
|
+
servicePageId: z118.string(),
|
|
23927
|
+
motionTaskId: z118.string(),
|
|
23928
|
+
motionVariantTaskId: z118.string().optional(),
|
|
23929
|
+
motionThirdTaskId: z118.string().optional(),
|
|
23930
|
+
imageTaskId: z118.string()
|
|
23900
23931
|
}),
|
|
23901
|
-
snapshotAt:
|
|
23932
|
+
snapshotAt: z118.string().nullable()
|
|
23902
23933
|
});
|
|
23903
23934
|
var DEMO_MODE_TEMPLATE_PROBLEMS = [
|
|
23904
23935
|
"not_found",
|
|
@@ -23909,31 +23940,33 @@ var DEMO_MODE_TEMPLATE_PROBLEMS = [
|
|
|
23909
23940
|
"no_video",
|
|
23910
23941
|
"no_creative"
|
|
23911
23942
|
];
|
|
23912
|
-
var DemoModeTemplateVerdictSchema =
|
|
23913
|
-
|
|
23914
|
-
ok:
|
|
23943
|
+
var DemoModeTemplateVerdictSchema = z118.discriminatedUnion("ok", [
|
|
23944
|
+
z118.object({
|
|
23945
|
+
ok: z118.literal(true)
|
|
23915
23946
|
}),
|
|
23916
|
-
|
|
23917
|
-
ok:
|
|
23918
|
-
problem:
|
|
23947
|
+
z118.object({
|
|
23948
|
+
ok: z118.literal(false),
|
|
23949
|
+
problem: z118.enum(DEMO_MODE_TEMPLATE_PROBLEMS)
|
|
23919
23950
|
})
|
|
23920
23951
|
]);
|
|
23921
|
-
var DemoModeValidationSchema =
|
|
23952
|
+
var DemoModeValidationSchema = z118.object({
|
|
23922
23953
|
brandId: DemoModeTemplateVerdictSchema,
|
|
23923
23954
|
servicePageId: DemoModeTemplateVerdictSchema,
|
|
23924
23955
|
motionTaskId: DemoModeTemplateVerdictSchema,
|
|
23956
|
+
motionVariantTaskId: DemoModeTemplateVerdictSchema.optional(),
|
|
23957
|
+
motionThirdTaskId: DemoModeTemplateVerdictSchema.optional(),
|
|
23925
23958
|
imageTaskId: DemoModeTemplateVerdictSchema
|
|
23926
23959
|
});
|
|
23927
|
-
var DemoModeJobSchema =
|
|
23960
|
+
var DemoModeJobSchema = z118.object({
|
|
23928
23961
|
flow: DemoModeFlowSchema,
|
|
23929
23962
|
step: DemoModeStepSchema,
|
|
23930
23963
|
/** brandId | servicePageOperationId | taskId según el flujo. */
|
|
23931
|
-
targetId:
|
|
23932
|
-
userId:
|
|
23964
|
+
targetId: z118.string().uuid(),
|
|
23965
|
+
userId: z118.string().min(1),
|
|
23933
23966
|
/** Solo marca: la generación de extracción que el guion completa. */
|
|
23934
|
-
generation:
|
|
23967
|
+
generation: z118.number().int().positive().optional(),
|
|
23935
23968
|
/** Solo `final`/`watchdog`: la parte del snapshot de ESTE flujo, congelada al empezar. */
|
|
23936
|
-
result:
|
|
23969
|
+
result: z118.unknown().optional()
|
|
23937
23970
|
});
|
|
23938
23971
|
|
|
23939
23972
|
// src/http.ts
|
|
@@ -24445,23 +24478,23 @@ import { InsufficientScopeError, InvalidTokenError } from "@modelcontextprotocol
|
|
|
24445
24478
|
import { createRemoteJWKSet as createRemoteJWKSet2, jwtVerify as jwtVerify2 } from "jose";
|
|
24446
24479
|
|
|
24447
24480
|
// src/auth/oauth-config.ts
|
|
24448
|
-
import { z as
|
|
24481
|
+
import { z as z119 } from "zod";
|
|
24449
24482
|
var MCP_RESOURCE = new URL("https://mcp.productmaker.app/mcp");
|
|
24450
24483
|
var MCP_SCOPE = "mcp:access";
|
|
24451
24484
|
var REFRESH_SCOPE = "offline_access";
|
|
24452
24485
|
var STATIC_CLIENT_ISSUER = new URL(MCP_RESOURCE.origin);
|
|
24453
|
-
var oauthEnvSchema =
|
|
24454
|
-
MCP_REMOTE_AUTH_MODE:
|
|
24455
|
-
MCP_AUTH0_ISSUER:
|
|
24456
|
-
MCP_AUTH0_AUDIENCE:
|
|
24486
|
+
var oauthEnvSchema = z119.object({
|
|
24487
|
+
MCP_REMOTE_AUTH_MODE: z119.literal("oauth"),
|
|
24488
|
+
MCP_AUTH0_ISSUER: z119.string().trim().min(1),
|
|
24489
|
+
MCP_AUTH0_AUDIENCE: z119.string().trim().refine((value) => value === MCP_RESOURCE.href, {
|
|
24457
24490
|
message: `must equal ${MCP_RESOURCE.href}`
|
|
24458
24491
|
}),
|
|
24459
|
-
MCP_AUTH0_CLIENT_ID:
|
|
24460
|
-
MCP_AUTH0_CLIENT_SECRET:
|
|
24461
|
-
PM_API_AUDIENCE:
|
|
24462
|
-
AUTH0_AUDIENCE:
|
|
24463
|
-
MCP_STATIC_CLIENT_ID:
|
|
24464
|
-
MCP_STATIC_CLIENT_SECRET:
|
|
24492
|
+
MCP_AUTH0_CLIENT_ID: z119.string().trim().min(1),
|
|
24493
|
+
MCP_AUTH0_CLIENT_SECRET: z119.string().trim().min(1),
|
|
24494
|
+
PM_API_AUDIENCE: z119.string().trim().min(1),
|
|
24495
|
+
AUTH0_AUDIENCE: z119.string().trim().min(1),
|
|
24496
|
+
MCP_STATIC_CLIENT_ID: z119.string().trim().min(1).optional(),
|
|
24497
|
+
MCP_STATIC_CLIENT_SECRET: z119.string().trim().min(1).optional()
|
|
24465
24498
|
});
|
|
24466
24499
|
function formatZodIssues(error) {
|
|
24467
24500
|
return error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join("; ");
|
|
@@ -24644,7 +24677,7 @@ var Auth0TokenVerifier = class {
|
|
|
24644
24677
|
}
|
|
24645
24678
|
};
|
|
24646
24679
|
|
|
24647
|
-
// src/
|
|
24680
|
+
// src/analytics.ts
|
|
24648
24681
|
import { PostHog } from "posthog-node";
|
|
24649
24682
|
var DEFAULT_POSTHOG_HOST = "https://us.i.posthog.com";
|
|
24650
24683
|
var REDACTED = "[REDACTED]";
|
|
@@ -24664,12 +24697,6 @@ var SENSITIVE_KEYS = /* @__PURE__ */ new Set([
|
|
|
24664
24697
|
var SENSITIVE_ASSIGNMENT_PATTERN = /(\b(?:access[_-]?token|authorization|client[_-]?secret|subject[_-]?token|refresh[_-]?token|id[_-]?token|api[_-]?key|token|secret|password|code)\b\s*[:=]\s*)(?:(bearer)\s+)?(?:(['"])(.*?)\3|([^\s,;&}"']+))/gi;
|
|
24665
24698
|
var BEARER_TOKEN_PATTERN = /\b(bearer\s+)([A-Za-z0-9._~+/=-]+)/gi;
|
|
24666
24699
|
var client = null;
|
|
24667
|
-
var KNOWN_MCP_OAUTH_ANALYTICS_EVENTS = [
|
|
24668
|
-
MCP_OAUTH_ANALYTICS_EVENTS.STARTED,
|
|
24669
|
-
MCP_OAUTH_ANALYTICS_EVENTS.CONNECTED,
|
|
24670
|
-
MCP_OAUTH_ANALYTICS_EVENTS.FAILED,
|
|
24671
|
-
MCP_OAUTH_ANALYTICS_EVENTS.SAFE_VARIANT
|
|
24672
|
-
];
|
|
24673
24700
|
function getPostHogClient() {
|
|
24674
24701
|
if (client) return client;
|
|
24675
24702
|
const apiKey = process.env.POSTHOG_API_KEY;
|
|
@@ -24722,18 +24749,7 @@ function sanitizeValue(value) {
|
|
|
24722
24749
|
return value.map((entry) => sanitizeValue(entry));
|
|
24723
24750
|
}
|
|
24724
24751
|
if (value && typeof value === "object") {
|
|
24725
|
-
return
|
|
24726
|
-
if (isSensitiveKey(key)) {
|
|
24727
|
-
return [
|
|
24728
|
-
key,
|
|
24729
|
-
REDACTED
|
|
24730
|
-
];
|
|
24731
|
-
}
|
|
24732
|
-
return [
|
|
24733
|
-
key,
|
|
24734
|
-
sanitizeValue(entry)
|
|
24735
|
-
];
|
|
24736
|
-
}));
|
|
24752
|
+
return sanitizeProperties(value);
|
|
24737
24753
|
}
|
|
24738
24754
|
if (typeof value === "string") {
|
|
24739
24755
|
return sanitizeString(value);
|
|
@@ -24741,21 +24757,40 @@ function sanitizeValue(value) {
|
|
|
24741
24757
|
return value;
|
|
24742
24758
|
}
|
|
24743
24759
|
__name(sanitizeValue, "sanitizeValue");
|
|
24760
|
+
function sanitizeProperties(value) {
|
|
24761
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [
|
|
24762
|
+
key,
|
|
24763
|
+
isSensitiveKey(key) ? REDACTED : sanitizeValue(entry)
|
|
24764
|
+
]));
|
|
24765
|
+
}
|
|
24766
|
+
__name(sanitizeProperties, "sanitizeProperties");
|
|
24767
|
+
function captureMcpAnalytics(event, subject, properties) {
|
|
24768
|
+
try {
|
|
24769
|
+
const posthog = getPostHogClient();
|
|
24770
|
+
if (!posthog) return;
|
|
24771
|
+
posthog.capture({
|
|
24772
|
+
distinctId: subject ?? "mcp_oauth_aggregate",
|
|
24773
|
+
event,
|
|
24774
|
+
properties: properties ? sanitizeProperties(properties) : void 0
|
|
24775
|
+
});
|
|
24776
|
+
} catch {
|
|
24777
|
+
}
|
|
24778
|
+
}
|
|
24779
|
+
__name(captureMcpAnalytics, "captureMcpAnalytics");
|
|
24780
|
+
|
|
24781
|
+
// src/oauth-analytics.ts
|
|
24782
|
+
var KNOWN_MCP_OAUTH_ANALYTICS_EVENTS = [
|
|
24783
|
+
MCP_OAUTH_ANALYTICS_EVENTS.STARTED,
|
|
24784
|
+
MCP_OAUTH_ANALYTICS_EVENTS.CONNECTED,
|
|
24785
|
+
MCP_OAUTH_ANALYTICS_EVENTS.FAILED,
|
|
24786
|
+
MCP_OAUTH_ANALYTICS_EVENTS.SAFE_VARIANT
|
|
24787
|
+
];
|
|
24744
24788
|
var OAuthAnalytics = class {
|
|
24745
24789
|
static {
|
|
24746
24790
|
__name(this, "OAuthAnalytics");
|
|
24747
24791
|
}
|
|
24748
24792
|
capture(event, subject, properties) {
|
|
24749
|
-
|
|
24750
|
-
if (!posthog) return;
|
|
24751
|
-
try {
|
|
24752
|
-
posthog.capture({
|
|
24753
|
-
distinctId: subject ?? "mcp_oauth_aggregate",
|
|
24754
|
-
event,
|
|
24755
|
-
properties: sanitizeValue(properties)
|
|
24756
|
-
});
|
|
24757
|
-
} catch {
|
|
24758
|
-
}
|
|
24793
|
+
captureMcpAnalytics(event, subject, properties);
|
|
24759
24794
|
}
|
|
24760
24795
|
};
|
|
24761
24796
|
|
|
@@ -25848,7 +25883,7 @@ var ApiClient = class {
|
|
|
25848
25883
|
};
|
|
25849
25884
|
|
|
25850
25885
|
// src/index.ts
|
|
25851
|
-
var MCP_VERSION = "12.1.
|
|
25886
|
+
var MCP_VERSION = "12.1.2";
|
|
25852
25887
|
|
|
25853
25888
|
// src/meta-upload-app.ts
|
|
25854
25889
|
import { readFileSync } from "fs";
|
|
@@ -25919,8 +25954,123 @@ function registerMediaUploadAppResource(server, resolveEndpoint) {
|
|
|
25919
25954
|
}
|
|
25920
25955
|
__name(registerMediaUploadAppResource, "registerMediaUploadAppResource");
|
|
25921
25956
|
|
|
25957
|
+
// src/task-results-app.ts
|
|
25958
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
25959
|
+
import { registerAppResource as registerAppResource2, RESOURCE_MIME_TYPE as RESOURCE_MIME_TYPE2 } from "@modelcontextprotocol/ext-apps/server";
|
|
25960
|
+
var TASK_RESULTS_APP_RESOURCE_URI = "ui://task-results/v1.html";
|
|
25961
|
+
var HTML_URL = new URL("./ui/task-results-app.html", import.meta.url);
|
|
25962
|
+
function assetOrigin(value) {
|
|
25963
|
+
if (!value) return null;
|
|
25964
|
+
try {
|
|
25965
|
+
const url = new URL(value);
|
|
25966
|
+
return url.protocol === "https:" && !url.username && !url.password ? url.origin : null;
|
|
25967
|
+
} catch {
|
|
25968
|
+
return null;
|
|
25969
|
+
}
|
|
25970
|
+
}
|
|
25971
|
+
__name(assetOrigin, "assetOrigin");
|
|
25972
|
+
function buildTaskResultsView(media, proxyBaseUrl) {
|
|
25973
|
+
const origin = assetOrigin(proxyBaseUrl);
|
|
25974
|
+
const safeUrl = /* @__PURE__ */ __name((value) => {
|
|
25975
|
+
if (!origin) return null;
|
|
25976
|
+
try {
|
|
25977
|
+
const url = new URL(value);
|
|
25978
|
+
return url.protocol === "https:" && url.origin === origin && url.pathname.startsWith("/assets/") && url.pathname.length > "/assets/".length && !url.username && !url.password ? url.href : null;
|
|
25979
|
+
} catch {
|
|
25980
|
+
return null;
|
|
25981
|
+
}
|
|
25982
|
+
}, "safeUrl");
|
|
25983
|
+
const images = media.images.flatMap((image, index) => {
|
|
25984
|
+
const url = safeUrl(image.url);
|
|
25985
|
+
return url ? [
|
|
25986
|
+
{
|
|
25987
|
+
url,
|
|
25988
|
+
alt: image.alt?.slice(0, 160) ?? `ProductMaker image ${index + 1}`
|
|
25989
|
+
}
|
|
25990
|
+
] : [];
|
|
25991
|
+
});
|
|
25992
|
+
const videos = media.videos.flatMap((video) => {
|
|
25993
|
+
const url = safeUrl(video.url);
|
|
25994
|
+
return url ? [
|
|
25995
|
+
{
|
|
25996
|
+
url,
|
|
25997
|
+
...video.label ? {
|
|
25998
|
+
label: video.label.slice(0, 120)
|
|
25999
|
+
} : {},
|
|
26000
|
+
...video.scriptRewritten === true ? {
|
|
26001
|
+
scriptRewritten: true
|
|
26002
|
+
} : {}
|
|
26003
|
+
}
|
|
26004
|
+
] : [];
|
|
26005
|
+
});
|
|
26006
|
+
const links = media.links.flatMap((link) => {
|
|
26007
|
+
const url = safeUrl(link.url);
|
|
26008
|
+
return url ? [
|
|
26009
|
+
{
|
|
26010
|
+
url,
|
|
26011
|
+
label: link.label?.slice(0, 120) ?? "Open result"
|
|
26012
|
+
}
|
|
26013
|
+
] : [];
|
|
26014
|
+
});
|
|
26015
|
+
return {
|
|
26016
|
+
state: images.length || videos.length || links.length ? "ready" : "empty",
|
|
26017
|
+
images,
|
|
26018
|
+
videos,
|
|
26019
|
+
links
|
|
26020
|
+
};
|
|
26021
|
+
}
|
|
26022
|
+
__name(buildTaskResultsView, "buildTaskResultsView");
|
|
26023
|
+
function taskResultsToolMeta() {
|
|
26024
|
+
return {
|
|
26025
|
+
ui: {
|
|
26026
|
+
resourceUri: TASK_RESULTS_APP_RESOURCE_URI
|
|
26027
|
+
},
|
|
26028
|
+
"openai/outputTemplate": TASK_RESULTS_APP_RESOURCE_URI
|
|
26029
|
+
};
|
|
26030
|
+
}
|
|
26031
|
+
__name(taskResultsToolMeta, "taskResultsToolMeta");
|
|
26032
|
+
function renderTaskResultsAppHtml(proxyBaseUrl) {
|
|
26033
|
+
return readFileSync2(HTML_URL, "utf8").replace("__PRODUCTMAKER_ASSET_ORIGIN__", JSON.stringify(assetOrigin(proxyBaseUrl)).replaceAll("<", "\\u003c"));
|
|
26034
|
+
}
|
|
26035
|
+
__name(renderTaskResultsAppHtml, "renderTaskResultsAppHtml");
|
|
26036
|
+
function registerTaskResultsAppResource(server, proxyBaseUrl) {
|
|
26037
|
+
const origin = assetOrigin(proxyBaseUrl);
|
|
26038
|
+
const resourceDomains = origin ? [
|
|
26039
|
+
origin
|
|
26040
|
+
] : [];
|
|
26041
|
+
const html = renderTaskResultsAppHtml(proxyBaseUrl);
|
|
26042
|
+
const meta = {
|
|
26043
|
+
ui: {
|
|
26044
|
+
csp: {
|
|
26045
|
+
resourceDomains,
|
|
26046
|
+
connectDomains: []
|
|
26047
|
+
}
|
|
26048
|
+
},
|
|
26049
|
+
"openai/widgetCSP": {
|
|
26050
|
+
resource_domains: resourceDomains,
|
|
26051
|
+
connect_domains: []
|
|
26052
|
+
},
|
|
26053
|
+
"openai/widgetDescription": "Displays the actual ProductMaker images and videos with playback controls and download links."
|
|
26054
|
+
};
|
|
26055
|
+
registerAppResource2(server, "ProductMaker task results", TASK_RESULTS_APP_RESOURCE_URI, {
|
|
26056
|
+
title: "Your creative",
|
|
26057
|
+
mimeType: RESOURCE_MIME_TYPE2,
|
|
26058
|
+
_meta: meta
|
|
26059
|
+
}, async () => ({
|
|
26060
|
+
contents: [
|
|
26061
|
+
{
|
|
26062
|
+
uri: TASK_RESULTS_APP_RESOURCE_URI,
|
|
26063
|
+
mimeType: RESOURCE_MIME_TYPE2,
|
|
26064
|
+
text: html,
|
|
26065
|
+
_meta: meta
|
|
26066
|
+
}
|
|
26067
|
+
]
|
|
26068
|
+
}));
|
|
26069
|
+
}
|
|
26070
|
+
__name(registerTaskResultsAppResource, "registerTaskResultsAppResource");
|
|
26071
|
+
|
|
25922
26072
|
// src/tools/tasks.ts
|
|
25923
|
-
import { z as
|
|
26073
|
+
import { z as z125 } from "zod";
|
|
25924
26074
|
|
|
25925
26075
|
// src/resolve-image.ts
|
|
25926
26076
|
import { lookup as dnsLookup } from "dns/promises";
|
|
@@ -26481,9 +26631,9 @@ async function resolveMediaRef(ref, opts) {
|
|
|
26481
26631
|
__name(resolveMediaRef, "resolveMediaRef");
|
|
26482
26632
|
|
|
26483
26633
|
// src/tools/shared.ts
|
|
26484
|
-
import { z as
|
|
26485
|
-
var Lang =
|
|
26486
|
-
var Country =
|
|
26634
|
+
import { z as z120 } from "zod";
|
|
26635
|
+
var Lang = z120.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);
|
|
26636
|
+
var Country = z120.string().min(2).max(3);
|
|
26487
26637
|
var LandingStrategyEnum = LandingStrategySchema;
|
|
26488
26638
|
var LandingImageFormatEnum = LandingImageFormatSchema;
|
|
26489
26639
|
var VideoPresetEnum = VideoPreset.extract([
|
|
@@ -26587,7 +26737,7 @@ function animationStyleApplies(videoPreset, angleNarratives) {
|
|
|
26587
26737
|
return ANIMATED_VIDEO_PRESETS.has(videoPreset ?? "") || (angleNarratives ?? []).some((n) => ANIMATED_NARRATIVE_STYLES.has(n));
|
|
26588
26738
|
}
|
|
26589
26739
|
__name(animationStyleApplies, "animationStyleApplies");
|
|
26590
|
-
var VideoTierEnum =
|
|
26740
|
+
var VideoTierEnum = z120.enum([
|
|
26591
26741
|
"basic"
|
|
26592
26742
|
]);
|
|
26593
26743
|
function resolveVideoTier(_tier) {
|
|
@@ -26645,10 +26795,10 @@ var ImageCreativeStyleEnum = ImageCreativeStyle;
|
|
|
26645
26795
|
var ImageCreativeArchetypeEnum = ImageCreativeArchetype;
|
|
26646
26796
|
var ImageCreativeVisualTreatmentEnum = ImageCreativeVisualTreatment;
|
|
26647
26797
|
var ImageCreativeAspectRatioEnum = ImageCreativeAspectRatio;
|
|
26648
|
-
var ImageRefSchema =
|
|
26649
|
-
url:
|
|
26650
|
-
path:
|
|
26651
|
-
assetId:
|
|
26798
|
+
var ImageRefSchema = z120.object({
|
|
26799
|
+
url: z120.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.'),
|
|
26800
|
+
path: z120.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`.'),
|
|
26801
|
+
assetId: z120.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.")
|
|
26652
26802
|
}).refine((v) => [
|
|
26653
26803
|
v.url,
|
|
26654
26804
|
v.path,
|
|
@@ -26656,11 +26806,11 @@ var ImageRefSchema = z119.object({
|
|
|
26656
26806
|
].filter(Boolean).length === 1, {
|
|
26657
26807
|
message: "each image entry must have exactly one of `url`, `path`, or `assetId`"
|
|
26658
26808
|
});
|
|
26659
|
-
var ImagesInput =
|
|
26809
|
+
var ImagesInput = z120.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
|
|
26660
26810
|
const assetCount = images.filter((image) => Boolean(image.assetId)).length;
|
|
26661
26811
|
if (assetCount > 0 && assetCount !== images.length) {
|
|
26662
26812
|
ctx.addIssue({
|
|
26663
|
-
code:
|
|
26813
|
+
code: z120.ZodIssueCode.custom,
|
|
26664
26814
|
message: "all image entries must use assetId, or all must use URL/path sources"
|
|
26665
26815
|
});
|
|
26666
26816
|
}
|
|
@@ -26741,14 +26891,14 @@ async function submitCreative(api, opts) {
|
|
|
26741
26891
|
});
|
|
26742
26892
|
}
|
|
26743
26893
|
__name(submitCreative, "submitCreative");
|
|
26744
|
-
var ResearchTargetCountryEnum =
|
|
26894
|
+
var ResearchTargetCountryEnum = z120.enum([
|
|
26745
26895
|
"CO",
|
|
26746
26896
|
"MX",
|
|
26747
26897
|
"PE",
|
|
26748
26898
|
"EC",
|
|
26749
26899
|
"CL"
|
|
26750
26900
|
]);
|
|
26751
|
-
var ResearchCategoryEnum =
|
|
26901
|
+
var ResearchCategoryEnum = z120.enum([
|
|
26752
26902
|
"auto",
|
|
26753
26903
|
"automotive",
|
|
26754
26904
|
"kitchen",
|
|
@@ -27543,7 +27693,7 @@ function approveRefusalMessage(reason) {
|
|
|
27543
27693
|
__name(approveRefusalMessage, "approveRefusalMessage");
|
|
27544
27694
|
|
|
27545
27695
|
// src/tools/task-outputs.ts
|
|
27546
|
-
import { z as
|
|
27696
|
+
import { z as z121 } from "zod";
|
|
27547
27697
|
|
|
27548
27698
|
// src/tools/conversational-review-format.ts
|
|
27549
27699
|
function escapeMarkdownText(value) {
|
|
@@ -27596,12 +27746,90 @@ __name(formatCredits, "formatCredits");
|
|
|
27596
27746
|
|
|
27597
27747
|
// src/tools/task-outputs.ts
|
|
27598
27748
|
var WEBAPP_BASE = "https://productmaker.app";
|
|
27599
|
-
|
|
27600
|
-
|
|
27601
|
-
|
|
27749
|
+
function proxifyServiceVideoResult(result, proxyBaseUrl) {
|
|
27750
|
+
if (!proxyBaseUrl || !isProxyEnabled()) return result;
|
|
27751
|
+
const rewrite = /* @__PURE__ */ __name((url, filename) => buildProxyUrl({
|
|
27752
|
+
r2Url: url,
|
|
27753
|
+
filename,
|
|
27754
|
+
proxyBaseUrl
|
|
27755
|
+
}) ?? url, "rewrite");
|
|
27756
|
+
const mg = result.motionGraphics;
|
|
27757
|
+
return {
|
|
27758
|
+
...result,
|
|
27759
|
+
...result.finalMp4Url ? {
|
|
27760
|
+
finalMp4Url: rewrite(result.finalMp4Url, "video-final.mp4")
|
|
27761
|
+
} : {},
|
|
27762
|
+
...result.concatMp4Url ? {
|
|
27763
|
+
concatMp4Url: rewrite(result.concatMp4Url, "video-voices.mp4")
|
|
27764
|
+
} : {},
|
|
27765
|
+
...mg ? {
|
|
27766
|
+
motionGraphics: {
|
|
27767
|
+
...mg,
|
|
27768
|
+
...Array.isArray(mg.variantUrls) ? {
|
|
27769
|
+
variantUrls: mg.variantUrls.map((url, i) => rewrite(url, `video-variant-${i + 2}.mp4`))
|
|
27770
|
+
} : {},
|
|
27771
|
+
...mg.cleanVideoUrl ? {
|
|
27772
|
+
cleanVideoUrl: rewrite(mg.cleanVideoUrl, "video-clean.mp4")
|
|
27773
|
+
} : {},
|
|
27774
|
+
...Array.isArray(mg.cleanVariantUrls) ? {
|
|
27775
|
+
cleanVariantUrls: mg.cleanVariantUrls.map((url, i) => rewrite(url, `video-clean-variant-${i + 2}.mp4`))
|
|
27776
|
+
} : {},
|
|
27777
|
+
...mg.previewUrl ? {
|
|
27778
|
+
previewUrl: rewrite(mg.previewUrl, "service-preview.png")
|
|
27779
|
+
} : {}
|
|
27780
|
+
}
|
|
27781
|
+
} : {}
|
|
27782
|
+
};
|
|
27783
|
+
}
|
|
27784
|
+
__name(proxifyServiceVideoResult, "proxifyServiceVideoResult");
|
|
27785
|
+
function serviceVideoResultMedia(result) {
|
|
27786
|
+
const mg = result.motionGraphics;
|
|
27787
|
+
const candidates = [
|
|
27788
|
+
{
|
|
27789
|
+
url: result.finalMp4Url,
|
|
27790
|
+
label: "Video final"
|
|
27791
|
+
},
|
|
27792
|
+
{
|
|
27793
|
+
url: result.concatMp4Url,
|
|
27794
|
+
label: "Video solo voces"
|
|
27795
|
+
},
|
|
27796
|
+
...(Array.isArray(mg?.variantUrls) ? mg.variantUrls : []).map((url, i) => ({
|
|
27797
|
+
url,
|
|
27798
|
+
label: `Versi\xF3n ${i + 2}`
|
|
27799
|
+
})),
|
|
27800
|
+
{
|
|
27801
|
+
url: mg?.cleanVideoUrl,
|
|
27802
|
+
label: "Video limpio"
|
|
27803
|
+
},
|
|
27804
|
+
...(Array.isArray(mg?.cleanVariantUrls) ? mg.cleanVariantUrls : []).map((url, i) => ({
|
|
27805
|
+
url,
|
|
27806
|
+
label: `Versi\xF3n limpia ${i + 2}`
|
|
27807
|
+
}))
|
|
27808
|
+
];
|
|
27809
|
+
const seen = /* @__PURE__ */ new Set();
|
|
27810
|
+
const videos = candidates.flatMap(({ url, label }) => {
|
|
27811
|
+
if (!url || seen.has(url)) return [];
|
|
27812
|
+
seen.add(url);
|
|
27813
|
+
return [
|
|
27814
|
+
{
|
|
27815
|
+
url,
|
|
27816
|
+
label
|
|
27817
|
+
}
|
|
27818
|
+
];
|
|
27819
|
+
});
|
|
27820
|
+
return {
|
|
27821
|
+
images: [],
|
|
27822
|
+
videos,
|
|
27823
|
+
links: videos
|
|
27824
|
+
};
|
|
27825
|
+
}
|
|
27826
|
+
__name(serviceVideoResultMedia, "serviceVideoResultMedia");
|
|
27827
|
+
var CreativeVariantIdentity = z121.object({
|
|
27828
|
+
variantTaskId: z121.string().uuid(),
|
|
27829
|
+
sourceTaskId: z121.string().uuid(),
|
|
27602
27830
|
kind: TaskCreativeVariantKind,
|
|
27603
27831
|
status: TaskStatusSchema,
|
|
27604
|
-
error:
|
|
27832
|
+
error: z121.string().optional()
|
|
27605
27833
|
});
|
|
27606
27834
|
function proxifyOutputs(outputs, proxyBaseUrl) {
|
|
27607
27835
|
if (!proxyBaseUrl || !isProxyEnabled()) return outputs;
|
|
@@ -28205,29 +28433,29 @@ ${parsed.data.error ? `${escapeMarkdownText(parsed.data.error)}
|
|
|
28205
28433
|
__name(renderVideoScriptMarkdown, "renderVideoScriptMarkdown");
|
|
28206
28434
|
|
|
28207
28435
|
// src/tools/media-presentation.ts
|
|
28208
|
-
import { z as
|
|
28209
|
-
var HttpsPresentationUrlSchema =
|
|
28436
|
+
import { z as z122 } from "zod";
|
|
28437
|
+
var HttpsPresentationUrlSchema = z122.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
|
|
28210
28438
|
var ProductMakerPreviewUrlSchema = HttpsPresentationUrlSchema.refine((value) => {
|
|
28211
28439
|
const hostname = new URL(value).hostname.toLowerCase();
|
|
28212
28440
|
return hostname === "productmaker.app" || hostname.endsWith(".productmaker.app");
|
|
28213
28441
|
}, "preview URL must be owned by ProductMaker");
|
|
28214
|
-
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) =>
|
|
28215
|
-
var PresentationImageSchema =
|
|
28216
|
-
kind:
|
|
28442
|
+
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z122.number().int().positive().max(maximum), "positiveIntAtMost");
|
|
28443
|
+
var PresentationImageSchema = z122.object({
|
|
28444
|
+
kind: z122.literal("image"),
|
|
28217
28445
|
url: HttpsPresentationUrlSchema,
|
|
28218
|
-
mimeType:
|
|
28446
|
+
mimeType: z122.enum([
|
|
28219
28447
|
"image/jpeg",
|
|
28220
28448
|
"image/png"
|
|
28221
28449
|
]),
|
|
28222
28450
|
byteSize: positiveIntAtMost(5 * 1024 * 1024),
|
|
28223
28451
|
width: positiveIntAtMost(16384),
|
|
28224
28452
|
height: positiveIntAtMost(16384),
|
|
28225
|
-
alt:
|
|
28453
|
+
alt: z122.string().trim().min(1).max(240)
|
|
28226
28454
|
}).strict();
|
|
28227
28455
|
var McpMediaPresentationSchema = PresentationImageSchema;
|
|
28228
|
-
var GalleryImageSchema =
|
|
28456
|
+
var GalleryImageSchema = z122.object({
|
|
28229
28457
|
url: ProductMakerPreviewUrlSchema,
|
|
28230
|
-
alt:
|
|
28458
|
+
alt: z122.string().trim().min(1).max(240)
|
|
28231
28459
|
});
|
|
28232
28460
|
var MCP_GALLERY_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
|
|
28233
28461
|
async function imageBlocks(image, transport) {
|
|
@@ -28284,12 +28512,12 @@ async function buildMcpMediaPresentationContent(rawPresentation, transport = "ht
|
|
|
28284
28512
|
];
|
|
28285
28513
|
}
|
|
28286
28514
|
__name(buildMcpMediaPresentationContent, "buildMcpMediaPresentationContent");
|
|
28287
|
-
var OwnedImagePreviewSchema =
|
|
28515
|
+
var OwnedImagePreviewSchema = z122.object({
|
|
28288
28516
|
url: HttpsPresentationUrlSchema.refine((value) => {
|
|
28289
28517
|
const url = new URL(value);
|
|
28290
28518
|
return !url.username && !url.password && !isPrivateHost(url.hostname);
|
|
28291
28519
|
}, "Preview URL must be public HTTPS without credentials"),
|
|
28292
|
-
alt:
|
|
28520
|
+
alt: z122.string().trim().min(1).max(240)
|
|
28293
28521
|
});
|
|
28294
28522
|
async function buildMcpImagePreviewContent(rawPreview, transport = "http") {
|
|
28295
28523
|
const preview2 = OwnedImagePreviewSchema.safeParse(rawPreview);
|
|
@@ -28304,6 +28532,53 @@ async function buildMcpImagePreviewContent(rawPreview, transport = "http") {
|
|
|
28304
28532
|
return imageBlocks(preview2.data, transport);
|
|
28305
28533
|
}
|
|
28306
28534
|
__name(buildMcpImagePreviewContent, "buildMcpImagePreviewContent");
|
|
28535
|
+
async function buildMcpGeneratedImageContent(rawItems, transport = "http") {
|
|
28536
|
+
const blocks = await Promise.all(rawItems.slice(0, MAX_IMAGE_CREATIVE_VARIANTS).map(async (rawItem, index) => {
|
|
28537
|
+
const preview2 = OwnedImagePreviewSchema.safeParse(rawItem);
|
|
28538
|
+
if (!preview2.success) {
|
|
28539
|
+
return [
|
|
28540
|
+
{
|
|
28541
|
+
type: "text",
|
|
28542
|
+
text: `Imagen ${index + 1}: vista previa bloqueada por seguridad. No generes ni recrees una imagen sustituta.`
|
|
28543
|
+
}
|
|
28544
|
+
];
|
|
28545
|
+
}
|
|
28546
|
+
const heading = {
|
|
28547
|
+
type: "text",
|
|
28548
|
+
text: `Imagen ${index + 1} de ProductMaker: ${preview2.data.alt}`
|
|
28549
|
+
};
|
|
28550
|
+
try {
|
|
28551
|
+
const [resolved] = await resolveImages([
|
|
28552
|
+
{
|
|
28553
|
+
url: preview2.data.url
|
|
28554
|
+
}
|
|
28555
|
+
], {
|
|
28556
|
+
transport,
|
|
28557
|
+
maxBytes: MCP_GALLERY_IMAGE_MAX_BYTES
|
|
28558
|
+
});
|
|
28559
|
+
if (resolved) {
|
|
28560
|
+
return [
|
|
28561
|
+
heading,
|
|
28562
|
+
{
|
|
28563
|
+
type: "image",
|
|
28564
|
+
data: resolved.buffer.toString("base64"),
|
|
28565
|
+
mimeType: resolved.mimetype
|
|
28566
|
+
}
|
|
28567
|
+
];
|
|
28568
|
+
}
|
|
28569
|
+
} catch {
|
|
28570
|
+
}
|
|
28571
|
+
return [
|
|
28572
|
+
heading,
|
|
28573
|
+
{
|
|
28574
|
+
type: "text",
|
|
28575
|
+
text: `Imagen ${index + 1}: no se pudo mostrar la imagen original de ProductMaker en este resultado. No generes ni recrees una imagen sustituta; usa el enlace protegido devuelto para esta imagen.`
|
|
28576
|
+
}
|
|
28577
|
+
];
|
|
28578
|
+
}));
|
|
28579
|
+
return blocks.flat();
|
|
28580
|
+
}
|
|
28581
|
+
__name(buildMcpGeneratedImageContent, "buildMcpGeneratedImageContent");
|
|
28307
28582
|
async function buildMcpImageGalleryContent(rawItems, transport = "http") {
|
|
28308
28583
|
const items = rawItems.slice(0, 5).map((rawItem, index) => ({
|
|
28309
28584
|
index,
|
|
@@ -28371,8 +28646,73 @@ async function buildMcpImageGalleryContent(rawItems, transport = "http") {
|
|
|
28371
28646
|
}
|
|
28372
28647
|
__name(buildMcpImageGalleryContent, "buildMcpImageGalleryContent");
|
|
28373
28648
|
|
|
28649
|
+
// src/media-delivery-analytics.ts
|
|
28650
|
+
var MCP_MEDIA_DELIVERY_ANALYTICS_EVENTS = {
|
|
28651
|
+
STARTED: "mcp_media_delivery_started",
|
|
28652
|
+
RESPONSE_DELIVERED: "mcp_media_response_delivered",
|
|
28653
|
+
FAILED: "mcp_media_delivery_failed",
|
|
28654
|
+
SAFE_VARIANT: "mcp_media_delivery_variant"
|
|
28655
|
+
};
|
|
28656
|
+
var RESPONSE_STATES = [
|
|
28657
|
+
"ready",
|
|
28658
|
+
"empty",
|
|
28659
|
+
"pending",
|
|
28660
|
+
"awaiting_review",
|
|
28661
|
+
"error"
|
|
28662
|
+
];
|
|
28663
|
+
var isRecord4 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value), "isRecord");
|
|
28664
|
+
function deliveryProperties(result) {
|
|
28665
|
+
const view = result._meta?.taskResults;
|
|
28666
|
+
const data = isRecord4(view) ? view : {};
|
|
28667
|
+
const responseState = RESPONSE_STATES.find((state) => state === data.state) ?? "unknown";
|
|
28668
|
+
const nativeImageCount = result.content.filter((block) => block.type === "image").length;
|
|
28669
|
+
const viewerImageCount = Array.isArray(data.images) ? data.images.length : 0;
|
|
28670
|
+
const viewerVideoCount = Array.isArray(data.videos) ? data.videos.length : 0;
|
|
28671
|
+
const imageFallbackCount = result.content.filter((block) => block.type === "text" && /^Imagen \d+: (?:no se pudo mostrar|vista previa bloqueada por seguridad)/.test(block.text)).length;
|
|
28672
|
+
const hasImages = nativeImageCount > 0 || viewerImageCount > 0 || imageFallbackCount > 0;
|
|
28673
|
+
return {
|
|
28674
|
+
measurement: "response_delivery",
|
|
28675
|
+
responseState,
|
|
28676
|
+
mediaKind: hasImages ? viewerVideoCount ? "mixed" : "image" : viewerVideoCount ? "video" : "none",
|
|
28677
|
+
nativeImageCount,
|
|
28678
|
+
viewerImageCount,
|
|
28679
|
+
viewerVideoCount,
|
|
28680
|
+
imageFallbackCount
|
|
28681
|
+
};
|
|
28682
|
+
}
|
|
28683
|
+
__name(deliveryProperties, "deliveryProperties");
|
|
28684
|
+
async function observeMcpMediaDelivery(fingerprint, work) {
|
|
28685
|
+
const subject = /^[a-f0-9]{32}$/.test(fingerprint) ? `mcp_credential_${fingerprint}` : "mcp_media_aggregate";
|
|
28686
|
+
const events = MCP_MEDIA_DELIVERY_ANALYTICS_EVENTS;
|
|
28687
|
+
captureMcpAnalytics(events.STARTED, subject, {
|
|
28688
|
+
measurement: "response_delivery"
|
|
28689
|
+
});
|
|
28690
|
+
let result;
|
|
28691
|
+
try {
|
|
28692
|
+
result = await work();
|
|
28693
|
+
} catch (error) {
|
|
28694
|
+
captureMcpAnalytics(events.FAILED, subject, {
|
|
28695
|
+
measurement: "response_delivery",
|
|
28696
|
+
reason: "exception"
|
|
28697
|
+
});
|
|
28698
|
+
throw error;
|
|
28699
|
+
}
|
|
28700
|
+
const properties = deliveryProperties(result);
|
|
28701
|
+
captureMcpAnalytics(events.SAFE_VARIANT, subject, properties);
|
|
28702
|
+
if (result.isError || properties.responseState === "error") {
|
|
28703
|
+
captureMcpAnalytics(events.FAILED, subject, {
|
|
28704
|
+
...properties,
|
|
28705
|
+
reason: result.isError ? "tool_error" : "delivery_error"
|
|
28706
|
+
});
|
|
28707
|
+
} else {
|
|
28708
|
+
captureMcpAnalytics(events.RESPONSE_DELIVERED, subject, properties);
|
|
28709
|
+
}
|
|
28710
|
+
return result;
|
|
28711
|
+
}
|
|
28712
|
+
__name(observeMcpMediaDelivery, "observeMcpMediaDelivery");
|
|
28713
|
+
|
|
28374
28714
|
// src/tools/animated-video.ts
|
|
28375
|
-
import { z as
|
|
28715
|
+
import { z as z123 } from "zod";
|
|
28376
28716
|
|
|
28377
28717
|
// src/tools/paid-confirmation.ts
|
|
28378
28718
|
function describeMarketStudyChoice(enabled) {
|
|
@@ -28485,17 +28825,17 @@ function sortCanonical(items) {
|
|
|
28485
28825
|
});
|
|
28486
28826
|
}
|
|
28487
28827
|
__name(sortCanonical, "sortCanonical");
|
|
28488
|
-
function
|
|
28828
|
+
function isRecord5(value) {
|
|
28489
28829
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28490
28830
|
}
|
|
28491
|
-
__name(
|
|
28831
|
+
__name(isRecord5, "isRecord");
|
|
28492
28832
|
function collectLanguageCodes(value, out) {
|
|
28493
28833
|
if (Array.isArray(value)) {
|
|
28494
28834
|
const items = value;
|
|
28495
28835
|
for (const item of items) collectLanguageCodes(item, out);
|
|
28496
28836
|
return out;
|
|
28497
28837
|
}
|
|
28498
|
-
if (!
|
|
28838
|
+
if (!isRecord5(value)) return out;
|
|
28499
28839
|
for (const [key, entry] of Object.entries(value)) {
|
|
28500
28840
|
if (LANGUAGE_FIELDS.has(key) && typeof entry === "string") {
|
|
28501
28841
|
const base = entry.trim().split(/[-_]/)[0]?.toLowerCase();
|
|
@@ -28541,7 +28881,7 @@ function normalizeForKey(value, languages) {
|
|
|
28541
28881
|
const items = value;
|
|
28542
28882
|
return items.map((item) => normalizeForKey(item, languages));
|
|
28543
28883
|
}
|
|
28544
|
-
if (!
|
|
28884
|
+
if (!isRecord5(value)) return value;
|
|
28545
28885
|
const out = {};
|
|
28546
28886
|
for (const [key, entry] of Object.entries(value)) {
|
|
28547
28887
|
if (PARAPHRASE_PRONE_FIELDS.has(key)) {
|
|
@@ -28621,30 +28961,30 @@ function hookVariantsLabel(count) {
|
|
|
28621
28961
|
return count === 1 ? "1 versi\xF3n del gancho" : `${count} versiones del gancho`;
|
|
28622
28962
|
}
|
|
28623
28963
|
__name(hookVariantsLabel, "hookVariantsLabel");
|
|
28624
|
-
var DurationInput =
|
|
28625
|
-
var CreateAnimatedVideoInput =
|
|
28626
|
-
action:
|
|
28964
|
+
var DurationInput = z123.union(MOTION_GRAPHICS_DURATIONS.map((d) => z123.literal(d)));
|
|
28965
|
+
var CreateAnimatedVideoInput = z123.object({
|
|
28966
|
+
action: z123.enum([
|
|
28627
28967
|
"prepare",
|
|
28628
28968
|
"status",
|
|
28629
28969
|
"cancel",
|
|
28630
28970
|
"generate"
|
|
28631
28971
|
]).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."),
|
|
28632
|
-
brandId:
|
|
28633
|
-
websiteCaptureId:
|
|
28634
|
-
generationRequestId:
|
|
28635
|
-
confirmed:
|
|
28972
|
+
brandId: z123.string().uuid().optional().describe("ID de un servicio propio y listo (de create_brand). Obligatorio al preparar y crear videos nuevos. Conserva el mismo brandId en reintentos; si recuperas una generaci\xF3n hist\xF3rica aceptada sin este campo, om\xEDtelo como en la petici\xF3n original. status/cancel no lo necesitan."),
|
|
28973
|
+
websiteCaptureId: z123.string().uuid().optional().describe("ID de la captura preparada. Obligatorio para status/cancel/generate; no inventarlo."),
|
|
28974
|
+
generationRequestId: z123.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."),
|
|
28975
|
+
confirmed: z123.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."),
|
|
28636
28976
|
// Plain text, not `.url()`: users type «cal.com», and the web accepts it.
|
|
28637
28977
|
// normalizeWebAddress (shared with the web) adds https:// and refuses
|
|
28638
28978
|
// anything that is not a public http(s) address.
|
|
28639
|
-
landingUrl:
|
|
28979
|
+
landingUrl: z123.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."),
|
|
28640
28980
|
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.'),
|
|
28641
28981
|
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.`),
|
|
28642
28982
|
language: MotionGraphicsLanguageSchema.optional().describe('Idioma de los textos del video: "es", "en" o "pt".'),
|
|
28643
28983
|
videoQuality: MotionGraphicsVideoQualitySchema.default(DEFAULT_MOTION_GRAPHICS_VIDEO_QUALITY).describe('Calidad IA: "economy" (econ\xF3mica) o "pro" (alta, por defecto). Afecta el precio de los clips IA.'),
|
|
28644
28984
|
videoResolution: MotionGraphicsVideoResolutionSchema.default(DEFAULT_MOTION_GRAPHICS_VIDEO_RESOLUTION).describe('Resoluci\xF3n: "480p" (por defecto), "720p" o "1080p". 1080p solo est\xE1 disponible con videoQuality="pro".'),
|
|
28645
|
-
notes:
|
|
28985
|
+
notes: z123.string().trim().max(MOTION_GRAPHICS_NOTES_MAX_CHARS).optional().describe("Opcional. Idea creativa, escenarios, acciones, di\xE1logo, voz o m\xFAsica en lenguaje natural. El director puede hacer solo motion graphics, escenas reales o escenas imposibles seg\xFAn la idea; las frases gu\xEDan el guion sin garantizar reproducci\xF3n exacta."),
|
|
28646
28986
|
hookVariants: MotionGraphicsHookVariantsSchema.optional().describe(`Opcional. Cantidad de videos independientes, de 1 a ${MOTION_GRAPHICS_HOOK_VARIANTS_MAX} (por defecto 1). Cada uno tiene su propio \xE1ngulo, guion y estilo visual, respetando notes, y reserva el precio completo de un video (ver la descripci\xF3n); \xFAsalo solo si el usuario lo pide.`),
|
|
28647
|
-
music:
|
|
28987
|
+
music: z123.boolean().optional().describe("Opcional. M\xFAsica y efectos dirigidos seg\xFAn el negocio y el video (por defecto true), con una copia adicional solo con voces. false entrega solo voces, sin m\xFAsica ni efectos a\xF1adidos ni el cargo de m\xFAsica. \xDAsalo solo si el usuario lo pide.")
|
|
28648
28988
|
}).strict();
|
|
28649
28989
|
function captureNextAction(capture) {
|
|
28650
28990
|
if (capture.status === "ready") return "Muestra la vista previa al usuario y confirma formato, duraci\xF3n, idioma, calidad IA, resoluci\xF3n y precio. Solo despu\xE9s llama create_animated_video con action=generate, este websiteCaptureId y confirmed=true.";
|
|
@@ -28697,33 +29037,33 @@ var FORMAT_LABELS = {
|
|
|
28697
29037
|
square: "cuadrado 1:1",
|
|
28698
29038
|
horizontal: "horizontal 16:9"
|
|
28699
29039
|
};
|
|
28700
|
-
var AnimatedVideoResultSchema =
|
|
28701
|
-
status:
|
|
29040
|
+
var AnimatedVideoResultSchema = z123.object({
|
|
29041
|
+
status: z123.enum([
|
|
28702
29042
|
"pending",
|
|
28703
29043
|
"done",
|
|
28704
29044
|
"error"
|
|
28705
29045
|
]),
|
|
28706
|
-
serviceMode:
|
|
28707
|
-
finalMp4Url:
|
|
28708
|
-
adCopy:
|
|
28709
|
-
adCopies:
|
|
28710
|
-
error:
|
|
28711
|
-
motionGraphics:
|
|
29046
|
+
serviceMode: z123.literal("motion_graphics"),
|
|
29047
|
+
finalMp4Url: z123.string().optional(),
|
|
29048
|
+
adCopy: z123.string().optional(),
|
|
29049
|
+
adCopies: z123.array(z123.string()).optional(),
|
|
29050
|
+
error: z123.string().optional(),
|
|
29051
|
+
motionGraphics: z123.object({
|
|
28712
29052
|
stage: MotionGraphicsStageSchema,
|
|
28713
29053
|
format: MotionGraphicsFormatSchema,
|
|
28714
|
-
durationSec:
|
|
28715
|
-
width:
|
|
28716
|
-
height:
|
|
29054
|
+
durationSec: z123.number(),
|
|
29055
|
+
width: z123.number().optional(),
|
|
29056
|
+
height: z123.number().optional(),
|
|
28717
29057
|
language: MotionGraphicsLanguageSchema.optional(),
|
|
28718
29058
|
videoQuality: MotionGraphicsVideoQualitySchema.optional().catch(void 0),
|
|
28719
29059
|
videoResolution: MotionGraphicsVideoResolutionSchema.optional().catch(void 0),
|
|
28720
|
-
creativeBatch:
|
|
29060
|
+
creativeBatch: z123.object({
|
|
28721
29061
|
index: MotionGraphicsHookVariantsSchema,
|
|
28722
29062
|
count: MotionGraphicsHookVariantsSchema,
|
|
28723
|
-
tasks:
|
|
28724
|
-
taskId:
|
|
29063
|
+
tasks: z123.array(z123.object({
|
|
29064
|
+
taskId: z123.string().uuid(),
|
|
28725
29065
|
index: MotionGraphicsHookVariantsSchema,
|
|
28726
|
-
status:
|
|
29066
|
+
status: z123.enum([
|
|
28727
29067
|
"queued",
|
|
28728
29068
|
"processing",
|
|
28729
29069
|
"done",
|
|
@@ -28731,29 +29071,29 @@ var AnimatedVideoResultSchema = z122.object({
|
|
|
28731
29071
|
])
|
|
28732
29072
|
})).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX)
|
|
28733
29073
|
}).optional().catch(void 0),
|
|
28734
|
-
queuedAt:
|
|
28735
|
-
jobsAhead:
|
|
28736
|
-
stageStartedAt:
|
|
28737
|
-
renderProgress:
|
|
29074
|
+
queuedAt: z123.string().optional(),
|
|
29075
|
+
jobsAhead: z123.number().int().nonnegative().optional(),
|
|
29076
|
+
stageStartedAt: z123.string().optional(),
|
|
29077
|
+
renderProgress: z123.number().optional(),
|
|
28738
29078
|
// AI clip fields (absent on a video paid before clips, or from an API
|
|
28739
29079
|
// that predates them). Lenient: an unreadable value is dropped
|
|
28740
29080
|
// instead of hiding the status.
|
|
28741
|
-
clipCount:
|
|
28742
|
-
clipsUsed:
|
|
28743
|
-
clipPriceCents:
|
|
28744
|
-
clipsRefunded:
|
|
29081
|
+
clipCount: z123.number().int().nonnegative().optional().catch(void 0),
|
|
29082
|
+
clipsUsed: z123.number().int().nonnegative().optional().catch(void 0),
|
|
29083
|
+
clipPriceCents: z123.number().finite().nonnegative().optional().catch(void 0),
|
|
29084
|
+
clipsRefunded: z123.number().int().nonnegative().optional().catch(void 0),
|
|
28745
29085
|
// Hook versions (absent from an API or a video before them): the
|
|
28746
29086
|
// count ordered and, once done, the signed URLs of the EXTRA versions
|
|
28747
29087
|
// (hook 2, hook 3); `finalMp4Url` is hook 1.
|
|
28748
|
-
hookVariants:
|
|
28749
|
-
cleanVideoUrl:
|
|
28750
|
-
cleanVariantUrls:
|
|
28751
|
-
variantUrls:
|
|
29088
|
+
hookVariants: z123.number().int().min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).optional().catch(void 0),
|
|
29089
|
+
cleanVideoUrl: z123.string().url().optional().catch(void 0),
|
|
29090
|
+
cleanVariantUrls: z123.array(z123.string().url()).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
|
|
29091
|
+
variantUrls: z123.array(z123.string().min(1)).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
|
|
28752
29092
|
// Extra hook versions given back, as the task recorded it once the
|
|
28753
29093
|
// refunds landed (absent until then, and from an API before it).
|
|
28754
|
-
variantsRefunded:
|
|
28755
|
-
activity:
|
|
28756
|
-
previewUrl:
|
|
29094
|
+
variantsRefunded: z123.number().int().nonnegative().optional().catch(void 0),
|
|
29095
|
+
activity: z123.array(MotionGraphicsActivitySchema).optional().catch(void 0),
|
|
29096
|
+
previewUrl: z123.string().optional()
|
|
28757
29097
|
}).passthrough()
|
|
28758
29098
|
}).passthrough();
|
|
28759
29099
|
function parseAnimatedVideoResult(value) {
|
|
@@ -29032,7 +29372,7 @@ function registerAnimatedVideoTools(server, api) {
|
|
|
29032
29372
|
nowMs: 0
|
|
29033
29373
|
})
|
|
29034
29374
|
});
|
|
29035
|
-
const parsedTaskIds =
|
|
29375
|
+
const parsedTaskIds = z123.array(z123.string().uuid()).min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).safeParse(created.taskIds);
|
|
29036
29376
|
const taskIds = parsedTaskIds.success && parsedTaskIds.data[0] === created.taskId ? parsedTaskIds.data : void 0;
|
|
29037
29377
|
const receipt = {
|
|
29038
29378
|
taskId: created.taskId,
|
|
@@ -29074,10 +29414,10 @@ function registerAnimatedVideoTools(server, api) {
|
|
|
29074
29414
|
__name(registerAnimatedVideoTools, "registerAnimatedVideoTools");
|
|
29075
29415
|
|
|
29076
29416
|
// src/tools/winning-product-image.ts
|
|
29077
|
-
import { z as
|
|
29078
|
-
var WinnerReferenceInput =
|
|
29079
|
-
runId:
|
|
29080
|
-
candidateSourceId:
|
|
29417
|
+
import { z as z124 } from "zod";
|
|
29418
|
+
var WinnerReferenceInput = z124.object({
|
|
29419
|
+
runId: z124.string().uuid(),
|
|
29420
|
+
candidateSourceId: z124.string().trim().min(1).max(160)
|
|
29081
29421
|
}).strict().describe("Referencia opaca de un producto devuelto por find_winning_products/get_product_research_run.");
|
|
29082
29422
|
async function resolveWinnerImages(api, winnerReference, images) {
|
|
29083
29423
|
if (!winnerReference) return images;
|
|
@@ -29114,62 +29454,62 @@ var createProductTaskSingleOutputDescription = renderCreateProductTaskAvoidWhenF
|
|
|
29114
29454
|
var CREATE_SERVICE_VIDEO_ON_MCP = PRODUCTMAKER_MCP_CAPABILITY_NAMES.includes("create_service_video");
|
|
29115
29455
|
var listTasksGuidance = getProductMakerCapabilityModelGuidance("list_tasks");
|
|
29116
29456
|
var editTaskDraftGuidance = getProductMakerCapabilityModelGuidance("edit_task_draft");
|
|
29117
|
-
var CreateProductTaskInput =
|
|
29457
|
+
var CreateProductTaskInput = z125.object({
|
|
29118
29458
|
images: ImagesInput.optional().describe("1\u20135 fotos del mismo producto. Omitir \xFAnicamente cuando projectId apunta a un proyecto propio con imagen guardada."),
|
|
29119
29459
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
29120
|
-
projectId:
|
|
29121
|
-
productUrl:
|
|
29460
|
+
projectId: z125.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
|
|
29461
|
+
productUrl: z125.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."),
|
|
29122
29462
|
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.'),
|
|
29123
29463
|
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.'),
|
|
29124
|
-
price:
|
|
29125
|
-
compareAtPrice:
|
|
29126
|
-
offer:
|
|
29127
|
-
paymentMethods:
|
|
29128
|
-
productContext:
|
|
29129
|
-
productLabel:
|
|
29464
|
+
price: z125.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.'),
|
|
29465
|
+
compareAtPrice: z125.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".'),
|
|
29466
|
+
offer: z125.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.'),
|
|
29467
|
+
paymentMethods: z125.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.'),
|
|
29468
|
+
productContext: z125.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."),
|
|
29469
|
+
productLabel: z125.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.'),
|
|
29130
29470
|
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.'),
|
|
29131
29471
|
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.'),
|
|
29132
|
-
durationSeconds:
|
|
29133
|
-
|
|
29134
|
-
|
|
29472
|
+
durationSeconds: z125.union([
|
|
29473
|
+
z125.literal(15),
|
|
29474
|
+
z125.literal(30)
|
|
29135
29475
|
]).default(15).describe("Opcional. Duraci\xF3n objetivo del video: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
|
|
29136
|
-
pauseForAngleReview:
|
|
29137
|
-
aiDecidesAll:
|
|
29476
|
+
pauseForAngleReview: z125.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."),
|
|
29477
|
+
aiDecidesAll: z125.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."),
|
|
29138
29478
|
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.'),
|
|
29139
29479
|
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.'),
|
|
29140
29480
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
29141
29481
|
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).'),
|
|
29142
|
-
videoAngleCount:
|
|
29482
|
+
videoAngleCount: z125.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."),
|
|
29143
29483
|
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.'),
|
|
29144
|
-
outputs:
|
|
29484
|
+
outputs: z125.array(z125.enum([
|
|
29145
29485
|
"landing",
|
|
29146
29486
|
"video",
|
|
29147
29487
|
"image"
|
|
29148
29488
|
])).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}`),
|
|
29149
|
-
includeInitialLandingGif:
|
|
29150
|
-
competitorScanEnabled:
|
|
29489
|
+
includeInitialLandingGif: z125.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."),
|
|
29490
|
+
competitorScanEnabled: z125.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."),
|
|
29151
29491
|
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.'),
|
|
29152
|
-
replicateWinnerWhenFound:
|
|
29153
|
-
brandId:
|
|
29154
|
-
actorId:
|
|
29492
|
+
replicateWinnerWhenFound: z125.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."),
|
|
29493
|
+
brandId: z125.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."),
|
|
29494
|
+
actorId: z125.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."),
|
|
29155
29495
|
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.'),
|
|
29156
|
-
creativeDirection:
|
|
29157
|
-
headline:
|
|
29158
|
-
subheadline:
|
|
29496
|
+
creativeDirection: z125.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.'),
|
|
29497
|
+
headline: z125.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."),
|
|
29498
|
+
subheadline: z125.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."),
|
|
29159
29499
|
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".'),
|
|
29160
29500
|
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".')
|
|
29161
29501
|
}).strict();
|
|
29162
|
-
var CreateServiceVideoInput =
|
|
29163
|
-
landingUrl:
|
|
29164
|
-
additionalContext:
|
|
29502
|
+
var CreateServiceVideoInput = z125.object({
|
|
29503
|
+
landingUrl: z125.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
|
|
29504
|
+
additionalContext: z125.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
|
|
29165
29505
|
language: Lang.describe("Idioma del video: es, en o pt."),
|
|
29166
|
-
voiceId:
|
|
29167
|
-
brandId:
|
|
29168
|
-
reviewMode:
|
|
29506
|
+
voiceId: z125.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.'),
|
|
29507
|
+
brandId: z125.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
|
|
29508
|
+
reviewMode: z125.enum([
|
|
29169
29509
|
"automatic",
|
|
29170
29510
|
"guided"
|
|
29171
29511
|
]).default("automatic").describe("automatic = la IA elige concepto y guion sin pausas; guided = el usuario aprueba concepto y storyboard."),
|
|
29172
|
-
videoPreset:
|
|
29512
|
+
videoPreset: z125.enum([
|
|
29173
29513
|
"auto",
|
|
29174
29514
|
"ugc_dynamic",
|
|
29175
29515
|
"ugc_how_to",
|
|
@@ -29179,128 +29519,128 @@ var CreateServiceVideoInput = z124.object({
|
|
|
29179
29519
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
29180
29520
|
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.')
|
|
29181
29521
|
}).strict();
|
|
29182
|
-
var GetTaskStatusInput =
|
|
29183
|
-
taskId:
|
|
29184
|
-
waitSeconds:
|
|
29522
|
+
var GetTaskStatusInput = z125.object({
|
|
29523
|
+
taskId: z125.string().min(1),
|
|
29524
|
+
waitSeconds: z125.number().int().min(0).max(120).optional()
|
|
29185
29525
|
});
|
|
29186
|
-
var ListTasksInput =
|
|
29187
|
-
limit:
|
|
29188
|
-
offset:
|
|
29189
|
-
search:
|
|
29526
|
+
var ListTasksInput = z125.object({
|
|
29527
|
+
limit: z125.number().int().min(1).max(50).optional(),
|
|
29528
|
+
offset: z125.number().int().min(0).optional(),
|
|
29529
|
+
search: z125.string().optional()
|
|
29190
29530
|
});
|
|
29191
29531
|
var MCP_REVIEW_LIST_FIELD_MAX = IMAGE_WIZARD_LIST_FIELD_MAX;
|
|
29192
29532
|
var MCP_REVIEW_FEATURE_ITEM_MAX = IMAGE_FEATURE_ITEM_MAX;
|
|
29193
|
-
var EditTaskDraftInput =
|
|
29194
|
-
taskId:
|
|
29195
|
-
angleIndex:
|
|
29196
|
-
angle:
|
|
29197
|
-
angle:
|
|
29198
|
-
buyerPersona:
|
|
29199
|
-
actor:
|
|
29200
|
-
actorId:
|
|
29201
|
-
gender:
|
|
29533
|
+
var EditTaskDraftInput = z125.object({
|
|
29534
|
+
taskId: z125.string().min(1),
|
|
29535
|
+
angleIndex: z125.number().int().min(0),
|
|
29536
|
+
angle: z125.object({
|
|
29537
|
+
angle: z125.string().min(1).max(480),
|
|
29538
|
+
buyerPersona: z125.string().min(1).max(360),
|
|
29539
|
+
actor: z125.string().min(1).max(360).optional(),
|
|
29540
|
+
actorId: z125.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."),
|
|
29541
|
+
gender: z125.enum([
|
|
29202
29542
|
"female",
|
|
29203
29543
|
"male"
|
|
29204
29544
|
]).optional(),
|
|
29205
|
-
scriptNotes:
|
|
29545
|
+
scriptNotes: z125.string().max(2e3).optional()
|
|
29206
29546
|
})
|
|
29207
29547
|
});
|
|
29208
|
-
var PendingActionPayload =
|
|
29209
|
-
|
|
29210
|
-
kind:
|
|
29548
|
+
var PendingActionPayload = z125.discriminatedUnion("kind", [
|
|
29549
|
+
z125.object({
|
|
29550
|
+
kind: z125.literal("product_reference_set_approval"),
|
|
29211
29551
|
scope: ProductReferenceScopeEnum.optional(),
|
|
29212
|
-
scopeKey:
|
|
29213
|
-
scopeSnapshotId:
|
|
29214
|
-
expectedScopeHash:
|
|
29552
|
+
scopeKey: z125.string().min(1).max(120).optional(),
|
|
29553
|
+
scopeSnapshotId: z125.string().uuid().optional(),
|
|
29554
|
+
expectedScopeHash: z125.string().min(1).max(128).optional(),
|
|
29215
29555
|
decision: ProductReferenceResolutionDecisionEnum,
|
|
29216
29556
|
reason: ProductReferenceRejectionReasonEnum.optional(),
|
|
29217
|
-
affectedRefKeys:
|
|
29218
|
-
affectedPhotoNumbers:
|
|
29219
|
-
recoveryAction:
|
|
29557
|
+
affectedRefKeys: z125.array(z125.string().min(1).max(200)).min(1).optional(),
|
|
29558
|
+
affectedPhotoNumbers: z125.array(z125.number().int().positive()).min(1).optional(),
|
|
29559
|
+
recoveryAction: z125.enum([
|
|
29220
29560
|
"remove",
|
|
29221
29561
|
"replace",
|
|
29222
29562
|
"upload",
|
|
29223
29563
|
"return_to_selection"
|
|
29224
29564
|
]).optional()
|
|
29225
29565
|
}),
|
|
29226
|
-
|
|
29227
|
-
kind:
|
|
29228
|
-
selectedPhotoNumbers:
|
|
29566
|
+
z125.object({
|
|
29567
|
+
kind: z125.literal("product_reference_confirmation"),
|
|
29568
|
+
selectedPhotoNumbers: z125.array(z125.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."),
|
|
29229
29569
|
userChoice: ProductReferenceUserChoiceEnum.optional(),
|
|
29230
|
-
confirmedProductNames:
|
|
29570
|
+
confirmedProductNames: z125.array(z125.string().min(1).max(120)).min(2).max(8).optional(),
|
|
29231
29571
|
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."),
|
|
29232
29572
|
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."),
|
|
29233
|
-
useMultiSceneShowcase:
|
|
29573
|
+
useMultiSceneShowcase: z125.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
|
|
29234
29574
|
}),
|
|
29235
|
-
|
|
29236
|
-
kind:
|
|
29575
|
+
z125.object({
|
|
29576
|
+
kind: z125.literal("angle_review_approval"),
|
|
29237
29577
|
// All edits are optional — empty action body just approves the
|
|
29238
29578
|
// backend-generated draft as-is. Field shapes mirror the angle-review
|
|
29239
29579
|
// request contracts in @packages/types/wizard.ts; the handler routes to
|
|
29240
29580
|
// the dedicated video/image/autopilot endpoint based on StatusResponse.kind.
|
|
29241
|
-
customAngle:
|
|
29581
|
+
customAngle: z125.string().min(1).max(480).optional(),
|
|
29242
29582
|
// Keep the shared MCP action within the strictest downstream contract:
|
|
29243
29583
|
// autopilot/image resume endpoints cap these fields at 1500 characters.
|
|
29244
|
-
painPoints:
|
|
29245
|
-
benefits:
|
|
29584
|
+
painPoints: z125.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
29585
|
+
benefits: z125.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
29246
29586
|
// Same policy as the two fields above: the strictest downstream contract
|
|
29247
29587
|
// wins. The image endpoint caps each feature at 240 while landing/video
|
|
29248
29588
|
// accept 300, and this single action routes to whichever the task is — so
|
|
29249
29589
|
// accepting 300 here turns a 250-character feature on an image task into
|
|
29250
29590
|
// an opaque HTTP 400 after the model already believed it had been saved.
|
|
29251
|
-
features:
|
|
29252
|
-
buyerPersona:
|
|
29591
|
+
features: z125.array(z125.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
|
|
29592
|
+
buyerPersona: z125.string().min(1).max(360).optional(),
|
|
29253
29593
|
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.'),
|
|
29254
|
-
actor:
|
|
29255
|
-
actorId:
|
|
29256
|
-
creativeDirection:
|
|
29257
|
-
selectedAngleNumbers:
|
|
29258
|
-
angleEdits:
|
|
29259
|
-
angleNumber:
|
|
29260
|
-
narrativeSelection:
|
|
29594
|
+
actor: z125.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."),
|
|
29595
|
+
actorId: z125.string().max(120).nullable().optional(),
|
|
29596
|
+
creativeDirection: z125.string().max(2e3).optional(),
|
|
29597
|
+
selectedAngleNumbers: z125.array(z125.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."),
|
|
29598
|
+
angleEdits: z125.array(z125.object({
|
|
29599
|
+
angleNumber: z125.number().int().positive(),
|
|
29600
|
+
narrativeSelection: z125.enum([
|
|
29261
29601
|
"market",
|
|
29262
29602
|
"guided"
|
|
29263
29603
|
]).optional().describe("Elecci\xF3n expl\xEDcita: market usa el estudio disponible; guided usa la narrativa elegida para este \xE1ngulo."),
|
|
29264
|
-
angle:
|
|
29265
|
-
buyerPersona:
|
|
29604
|
+
angle: z125.string().min(1).max(480).optional(),
|
|
29605
|
+
buyerPersona: z125.string().min(1).max(360).optional(),
|
|
29266
29606
|
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.'),
|
|
29267
|
-
actor:
|
|
29268
|
-
actorId:
|
|
29269
|
-
creativeDirection:
|
|
29607
|
+
actor: z125.string().min(1).max(360).optional(),
|
|
29608
|
+
actorId: z125.string().max(120).nullable().optional(),
|
|
29609
|
+
creativeDirection: z125.string().max(2e3).optional()
|
|
29270
29610
|
}).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)."),
|
|
29271
|
-
gapDurationSeconds:
|
|
29272
|
-
|
|
29273
|
-
|
|
29611
|
+
gapDurationSeconds: z125.union([
|
|
29612
|
+
z125.literal(15),
|
|
29613
|
+
z125.literal(30)
|
|
29274
29614
|
]).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.")
|
|
29275
29615
|
}),
|
|
29276
|
-
|
|
29277
|
-
kind:
|
|
29278
|
-
angleId:
|
|
29279
|
-
angleNumber:
|
|
29280
|
-
content:
|
|
29281
|
-
creativeDirection:
|
|
29282
|
-
actor:
|
|
29616
|
+
z125.object({
|
|
29617
|
+
kind: z125.literal("service_angle_approval"),
|
|
29618
|
+
angleId: z125.string().uuid().optional(),
|
|
29619
|
+
angleNumber: z125.number().int().positive().optional(),
|
|
29620
|
+
content: z125.string().min(1).max(480).optional(),
|
|
29621
|
+
creativeDirection: z125.string().min(1).max(1500).optional(),
|
|
29622
|
+
actor: z125.string().min(1).max(360).optional()
|
|
29283
29623
|
}),
|
|
29284
|
-
|
|
29285
|
-
kind:
|
|
29286
|
-
voiceovers:
|
|
29287
|
-
visualDirections:
|
|
29288
|
-
voiceoversByScene:
|
|
29289
|
-
visualDirectionsByScene:
|
|
29624
|
+
z125.object({
|
|
29625
|
+
kind: z125.literal("service_script_approval"),
|
|
29626
|
+
voiceovers: z125.record(z125.string(), z125.string().min(1).max(600)).optional(),
|
|
29627
|
+
visualDirections: z125.record(z125.string(), z125.string().min(1).max(1200)).optional(),
|
|
29628
|
+
voiceoversByScene: z125.record(z125.string(), z125.string().min(1).max(600)).optional(),
|
|
29629
|
+
visualDirectionsByScene: z125.record(z125.string(), z125.string().min(1).max(1200)).optional()
|
|
29290
29630
|
})
|
|
29291
29631
|
]);
|
|
29292
|
-
var ResolvePendingActionInput =
|
|
29293
|
-
taskId:
|
|
29632
|
+
var ResolvePendingActionInput = z125.object({
|
|
29633
|
+
taskId: z125.string().min(1),
|
|
29294
29634
|
action: PendingActionPayload
|
|
29295
29635
|
}).strict();
|
|
29296
29636
|
function resolveVariantConfirmVideoTier(action) {
|
|
29297
29637
|
return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
|
|
29298
29638
|
}
|
|
29299
29639
|
__name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
|
|
29300
|
-
var StatusForResolveSchema =
|
|
29640
|
+
var StatusForResolveSchema = z125.object({
|
|
29301
29641
|
// Metadata used to select the backend resume contract. Older API responses
|
|
29302
29642
|
// may omit these fields, so the resolver keeps the generic fallback.
|
|
29303
|
-
kind:
|
|
29643
|
+
kind: z125.enum([
|
|
29304
29644
|
"autopilot",
|
|
29305
29645
|
"video",
|
|
29306
29646
|
"image",
|
|
@@ -29308,18 +29648,18 @@ var StatusForResolveSchema = z124.object({
|
|
|
29308
29648
|
"mix",
|
|
29309
29649
|
"service"
|
|
29310
29650
|
]).optional(),
|
|
29311
|
-
selectedOutputs:
|
|
29651
|
+
selectedOutputs: z125.array(z125.enum([
|
|
29312
29652
|
"landing",
|
|
29313
29653
|
"video",
|
|
29314
29654
|
"image"
|
|
29315
29655
|
])).optional(),
|
|
29316
|
-
videoAngleCount:
|
|
29317
|
-
ugcFormat:
|
|
29656
|
+
videoAngleCount: z125.number().int().min(1).max(3).optional(),
|
|
29657
|
+
ugcFormat: z125.enum([
|
|
29318
29658
|
"single_8s",
|
|
29319
29659
|
"single_15s",
|
|
29320
29660
|
"double_30s"
|
|
29321
29661
|
]).optional(),
|
|
29322
|
-
videoStyle:
|
|
29662
|
+
videoStyle: z125.enum([
|
|
29323
29663
|
"ugc",
|
|
29324
29664
|
"cartoon_3d",
|
|
29325
29665
|
"product_only",
|
|
@@ -29329,13 +29669,13 @@ var StatusForResolveSchema = z124.object({
|
|
|
29329
29669
|
videoQuality: VideoQualityEnum.optional(),
|
|
29330
29670
|
videoRouteId: VideoRouteIdEnum.optional(),
|
|
29331
29671
|
videoModel: TaskVideoModelEnum.optional(),
|
|
29332
|
-
videoTier:
|
|
29672
|
+
videoTier: z125.enum([
|
|
29333
29673
|
"legacy",
|
|
29334
29674
|
"standard",
|
|
29335
29675
|
"pro",
|
|
29336
29676
|
"single_call"
|
|
29337
29677
|
]).optional(),
|
|
29338
|
-
videoResolution:
|
|
29678
|
+
videoResolution: z125.enum([
|
|
29339
29679
|
"480p",
|
|
29340
29680
|
"720p"
|
|
29341
29681
|
]).optional(),
|
|
@@ -29343,60 +29683,60 @@ var StatusForResolveSchema = z124.object({
|
|
|
29343
29683
|
// A task created before a narrative was blocked/hidden must still parse,
|
|
29344
29684
|
// or resolve_pending_action could never approve it.
|
|
29345
29685
|
narrativeStyle: NarrativeStyle.optional(),
|
|
29346
|
-
pauseForVideoScriptReview:
|
|
29347
|
-
pendingUserAction:
|
|
29348
|
-
kind:
|
|
29349
|
-
candidateGrouping:
|
|
29350
|
-
selectedImageUrls:
|
|
29351
|
-
proposedProductNames:
|
|
29686
|
+
pauseForVideoScriptReview: z125.boolean().optional(),
|
|
29687
|
+
pendingUserAction: z125.object({
|
|
29688
|
+
kind: z125.string(),
|
|
29689
|
+
candidateGrouping: z125.string().optional(),
|
|
29690
|
+
selectedImageUrls: z125.array(z125.string()).optional(),
|
|
29691
|
+
proposedProductNames: z125.array(z125.string()).optional(),
|
|
29352
29692
|
// Adaptive reference questions are server-owned. Echo only the evidence
|
|
29353
29693
|
// identity and the choices shown by the current snapshot; never accept a
|
|
29354
29694
|
// client-supplied reference set as authorization.
|
|
29355
|
-
options:
|
|
29356
|
-
mode:
|
|
29695
|
+
options: z125.array(ProductReferenceUserChoiceEnum).max(4).optional(),
|
|
29696
|
+
mode: z125.enum([
|
|
29357
29697
|
"question",
|
|
29358
29698
|
"visual_recovery"
|
|
29359
29699
|
]).optional(),
|
|
29360
29700
|
/** Hand-mirrored from packages/types result.ts — see CLAUDE.md § MCP Server Sync. */
|
|
29361
|
-
canKeepSelection:
|
|
29362
|
-
decisionKey:
|
|
29363
|
-
questionOrdinal:
|
|
29364
|
-
questionCeiling:
|
|
29365
|
-
|
|
29366
|
-
|
|
29701
|
+
canKeepSelection: z125.boolean().optional(),
|
|
29702
|
+
decisionKey: z125.string().optional(),
|
|
29703
|
+
questionOrdinal: z125.number().int().min(1).max(5).optional(),
|
|
29704
|
+
questionCeiling: z125.union([
|
|
29705
|
+
z125.literal(3),
|
|
29706
|
+
z125.literal(5)
|
|
29367
29707
|
]).optional(),
|
|
29368
|
-
referenceEvidenceVersion:
|
|
29369
|
-
expectedEvidenceHash:
|
|
29370
|
-
question:
|
|
29371
|
-
prompt:
|
|
29372
|
-
helpText:
|
|
29373
|
-
options:
|
|
29708
|
+
referenceEvidenceVersion: z125.number().int().positive().optional(),
|
|
29709
|
+
expectedEvidenceHash: z125.string().optional(),
|
|
29710
|
+
question: z125.object({
|
|
29711
|
+
prompt: z125.string().min(1).max(240),
|
|
29712
|
+
helpText: z125.string().min(1).max(300).optional(),
|
|
29713
|
+
options: z125.array(z125.object({
|
|
29374
29714
|
value: ProductReferenceUserChoiceEnum,
|
|
29375
|
-
label:
|
|
29376
|
-
description:
|
|
29715
|
+
label: z125.string().min(1).max(120),
|
|
29716
|
+
description: z125.string().min(1).max(240).optional()
|
|
29377
29717
|
})).min(2).max(4)
|
|
29378
29718
|
}).optional(),
|
|
29379
29719
|
scope: ProductReferenceScopeEnum.optional(),
|
|
29380
|
-
scopeKey:
|
|
29381
|
-
scopeSnapshotId:
|
|
29382
|
-
scopeHash:
|
|
29383
|
-
baseReferenceSetHash:
|
|
29384
|
-
phase:
|
|
29720
|
+
scopeKey: z125.string().optional(),
|
|
29721
|
+
scopeSnapshotId: z125.string().uuid().optional(),
|
|
29722
|
+
scopeHash: z125.string().optional(),
|
|
29723
|
+
baseReferenceSetHash: z125.string().optional(),
|
|
29724
|
+
phase: z125.enum([
|
|
29385
29725
|
"preparation",
|
|
29386
29726
|
"final"
|
|
29387
29727
|
]).optional(),
|
|
29388
|
-
selectedRefKeys:
|
|
29389
|
-
allowedDecisions:
|
|
29390
|
-
previews:
|
|
29391
|
-
refKey:
|
|
29728
|
+
selectedRefKeys: z125.array(z125.string().min(1).max(200)).optional(),
|
|
29729
|
+
allowedDecisions: z125.array(ProductReferenceResolutionDecisionEnum).optional(),
|
|
29730
|
+
previews: z125.array(z125.object({
|
|
29731
|
+
refKey: z125.string().min(1).max(200)
|
|
29392
29732
|
}).passthrough()).optional(),
|
|
29393
|
-
customAngleDraft:
|
|
29394
|
-
painPointsDraft:
|
|
29395
|
-
benefitsDraft:
|
|
29396
|
-
featuresDraft:
|
|
29397
|
-
angleOptions:
|
|
29398
|
-
index:
|
|
29399
|
-
angle:
|
|
29733
|
+
customAngleDraft: z125.string().optional(),
|
|
29734
|
+
painPointsDraft: z125.string().optional(),
|
|
29735
|
+
benefitsDraft: z125.string().optional(),
|
|
29736
|
+
featuresDraft: z125.array(z125.string()).optional(),
|
|
29737
|
+
angleOptions: z125.array(z125.object({
|
|
29738
|
+
index: z125.number().int().nonnegative(),
|
|
29739
|
+
angle: z125.string().min(1)
|
|
29400
29740
|
}).passthrough()).min(1).max(5).optional(),
|
|
29401
29741
|
// Recommendation consumed only when the caller explicitly sends
|
|
29402
29742
|
// gapDurationSeconds: 30 in the angle approval action.
|
|
@@ -29406,17 +29746,17 @@ var StatusForResolveSchema = z124.object({
|
|
|
29406
29746
|
// keys. `actorId` (the saved custom actor the picker stored) was silently
|
|
29407
29747
|
// dropped here, so the approval handler below could not echo it back on the
|
|
29408
29748
|
// PATCH — the selection looked accepted and reached no render.
|
|
29409
|
-
angles:
|
|
29410
|
-
id:
|
|
29411
|
-
content:
|
|
29412
|
-
creativeDirection:
|
|
29413
|
-
actor:
|
|
29414
|
-
actorId:
|
|
29749
|
+
angles: z125.array(z125.object({
|
|
29750
|
+
id: z125.string().uuid(),
|
|
29751
|
+
content: z125.string(),
|
|
29752
|
+
creativeDirection: z125.string(),
|
|
29753
|
+
actor: z125.string(),
|
|
29754
|
+
actorId: z125.string().nullable().optional()
|
|
29415
29755
|
}).passthrough()).optional(),
|
|
29416
|
-
panels:
|
|
29417
|
-
beatId:
|
|
29418
|
-
voiceover:
|
|
29419
|
-
visualDirection:
|
|
29756
|
+
panels: z125.array(z125.object({
|
|
29757
|
+
beatId: z125.string(),
|
|
29758
|
+
voiceover: z125.string(),
|
|
29759
|
+
visualDirection: z125.string()
|
|
29420
29760
|
}).passthrough()).optional()
|
|
29421
29761
|
}).optional()
|
|
29422
29762
|
}).passthrough();
|
|
@@ -29769,8 +30109,8 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
29769
30109
|
server.registerTool("verify_landing_commerce", {
|
|
29770
30110
|
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.",
|
|
29771
30111
|
inputSchema: {
|
|
29772
|
-
taskId:
|
|
29773
|
-
editId:
|
|
30112
|
+
taskId: z125.string().uuid(),
|
|
30113
|
+
editId: z125.string().uuid()
|
|
29774
30114
|
},
|
|
29775
30115
|
annotations: OVERWRITES_EXTERNAL
|
|
29776
30116
|
}, async (input) => {
|
|
@@ -29791,16 +30131,28 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
29791
30131
|
}
|
|
29792
30132
|
});
|
|
29793
30133
|
server.registerTool("get_task_status", {
|
|
29794
|
-
description: `Devuelve estado y outputs. Sigue llam\xE1ndola hasta done/error o una review; un timeout significa que sigue corriendo. Cuando aparece pendingUserAction, la respuesta a\xF1ade Markdown conversacional con el draft y opciones: mu\xE9stralo, pregunta y espera. Usa resolve_pending_action s\xF3lo tras la respuesta del usuario o delegaci\xF3n expl\xEDcita. Nunca expongas IDs, hashes ni payloads t\xE9cnicos. Despu\xE9s de resolver una review, sigue reviewNextAction cuando exista; s\xF3lo vuelve a get_task_status cuando esa transici\xF3n no exista o cuando get_video_script termine en approved/skipped. En un video animado, ${UNTRUSTED_SITE_TEXT_NOTE}`,
|
|
30134
|
+
description: `Devuelve estado y outputs. Sigue llam\xE1ndola hasta done/error o una review; un timeout significa que sigue corriendo. Cuando aparece pendingUserAction, la respuesta a\xF1ade Markdown conversacional con el draft y opciones: mu\xE9stralo, pregunta y espera. Usa resolve_pending_action s\xF3lo tras la respuesta del usuario o delegaci\xF3n expl\xEDcita. Nunca expongas IDs, hashes ni payloads t\xE9cnicos. Despu\xE9s de resolver una review, sigue reviewNextAction cuando exista; s\xF3lo vuelve a get_task_status cuando esa transici\xF3n no exista o cuando get_video_script termine en approved/skipped. Entrega \xFAnicamente los medios originales de ProductMaker en el visor y los bloques de imagen; nunca los sustituyas ni recrees con otra herramienta. En un video animado, ${UNTRUSTED_SITE_TEXT_NOTE}`,
|
|
29795
30135
|
inputSchema: GetTaskStatusInput.shape,
|
|
29796
|
-
annotations: READS_INTERNAL
|
|
29797
|
-
|
|
30136
|
+
annotations: READS_INTERNAL,
|
|
30137
|
+
_meta: taskResultsToolMeta()
|
|
30138
|
+
}, async (input, extra) => observeMcpMediaDelivery(api.fingerprint(), async () => {
|
|
29798
30139
|
try {
|
|
29799
30140
|
const signal = extra?.signal;
|
|
29800
30141
|
const fetcher = /* @__PURE__ */ __name(() => api.getJson(`/v1/status/${encodeURIComponent(input.taskId)}`, {
|
|
29801
30142
|
signal
|
|
29802
30143
|
}), "fetcher");
|
|
29803
30144
|
const snapshot = await pollStatus(fetcher, input.waitSeconds ?? 0, signal);
|
|
30145
|
+
const statusMeta = {
|
|
30146
|
+
taskResults: {
|
|
30147
|
+
state: snapshot.status === "error" ? "error" : [
|
|
30148
|
+
"awaiting_review",
|
|
30149
|
+
"waiting_for_user"
|
|
30150
|
+
].includes(snapshot.status) ? "awaiting_review" : "pending",
|
|
30151
|
+
images: [],
|
|
30152
|
+
videos: [],
|
|
30153
|
+
links: []
|
|
30154
|
+
}
|
|
30155
|
+
};
|
|
29804
30156
|
if (snapshot.status !== "done") {
|
|
29805
30157
|
const review = renderPendingActionMarkdown(snapshot);
|
|
29806
30158
|
if (review) {
|
|
@@ -29819,14 +30171,29 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
29819
30171
|
}) ?? review : review
|
|
29820
30172
|
}
|
|
29821
30173
|
],
|
|
29822
|
-
structuredContent: snapshot
|
|
30174
|
+
structuredContent: snapshot,
|
|
30175
|
+
_meta: {
|
|
30176
|
+
taskResults: {
|
|
30177
|
+
...statusMeta.taskResults,
|
|
30178
|
+
state: "awaiting_review"
|
|
30179
|
+
}
|
|
30180
|
+
}
|
|
29823
30181
|
};
|
|
29824
30182
|
}
|
|
29825
30183
|
if (snapshot.kind === "service") {
|
|
29826
|
-
const
|
|
29827
|
-
if (
|
|
30184
|
+
const rawAnimated = await fetchAnimatedVideoResult(api, input.taskId, signal, "serviceMode" in snapshot ? snapshot.serviceMode : void 0);
|
|
30185
|
+
if (rawAnimated) {
|
|
30186
|
+
const animated = proxifyServiceVideoResult(rawAnimated, proxyBaseUrl);
|
|
29828
30187
|
const continuation2 = buildPollingContinuation(snapshot);
|
|
30188
|
+
const view = buildTaskResultsView(serviceVideoResultMedia(animated), proxyBaseUrl);
|
|
29829
30189
|
return {
|
|
30190
|
+
structuredContent: {
|
|
30191
|
+
...snapshot,
|
|
30192
|
+
animatedVideo: toAgentFacingAnimatedVideo(animated)
|
|
30193
|
+
},
|
|
30194
|
+
_meta: view.state === "ready" ? {
|
|
30195
|
+
taskResults: view
|
|
30196
|
+
} : statusMeta,
|
|
29830
30197
|
content: [
|
|
29831
30198
|
{
|
|
29832
30199
|
type: "text",
|
|
@@ -29855,6 +30222,7 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
29855
30222
|
const continuation = buildPollingContinuation(snapshot);
|
|
29856
30223
|
if (continuation) {
|
|
29857
30224
|
return {
|
|
30225
|
+
_meta: statusMeta,
|
|
29858
30226
|
content: [
|
|
29859
30227
|
{
|
|
29860
30228
|
type: "text",
|
|
@@ -29870,15 +30238,26 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
29870
30238
|
]
|
|
29871
30239
|
};
|
|
29872
30240
|
}
|
|
29873
|
-
return
|
|
30241
|
+
return {
|
|
30242
|
+
...asText(snapshot),
|
|
30243
|
+
_meta: statusMeta
|
|
30244
|
+
};
|
|
29874
30245
|
}
|
|
29875
30246
|
if (snapshot.kind === "service") {
|
|
29876
|
-
const
|
|
30247
|
+
const rawResult = await api.getJson(`/v1/tasks/${encodeURIComponent(input.taskId)}/service-result`, {
|
|
29877
30248
|
signal
|
|
29878
30249
|
});
|
|
30250
|
+
const result = proxifyServiceVideoResult(rawResult, proxyBaseUrl);
|
|
29879
30251
|
const animated = parseAnimatedVideoResult(result);
|
|
29880
30252
|
if (animated) {
|
|
29881
30253
|
return {
|
|
30254
|
+
structuredContent: {
|
|
30255
|
+
...snapshot,
|
|
30256
|
+
result: toAgentFacingAnimatedVideo(animated)
|
|
30257
|
+
},
|
|
30258
|
+
_meta: {
|
|
30259
|
+
taskResults: buildTaskResultsView(serviceVideoResultMedia(animated), proxyBaseUrl)
|
|
30260
|
+
},
|
|
29882
30261
|
content: [
|
|
29883
30262
|
{
|
|
29884
30263
|
type: "text",
|
|
@@ -29895,6 +30274,13 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
29895
30274
|
};
|
|
29896
30275
|
}
|
|
29897
30276
|
return {
|
|
30277
|
+
structuredContent: {
|
|
30278
|
+
...snapshot,
|
|
30279
|
+
result
|
|
30280
|
+
},
|
|
30281
|
+
_meta: {
|
|
30282
|
+
taskResults: buildTaskResultsView(serviceVideoResultMedia(result), proxyBaseUrl)
|
|
30283
|
+
},
|
|
29898
30284
|
content: [
|
|
29899
30285
|
{
|
|
29900
30286
|
type: "text",
|
|
@@ -29916,13 +30302,39 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
29916
30302
|
const rawOutputs = await fetchTaskOutputs(api, input.taskId, {
|
|
29917
30303
|
signal
|
|
29918
30304
|
});
|
|
29919
|
-
const
|
|
29920
|
-
|
|
29921
|
-
|
|
29922
|
-
|
|
29923
|
-
}, transport)).filter((block) => block.type === "image") : [];
|
|
30305
|
+
const imageContent = await buildMcpGeneratedImageContent(rawOutputs.images.map((image, i) => ({
|
|
30306
|
+
url: image.url,
|
|
30307
|
+
alt: `Imagen ${i + 1}`
|
|
30308
|
+
})), transport);
|
|
29924
30309
|
const outputs = proxifyOutputs(rawOutputs, proxyBaseUrl);
|
|
30310
|
+
const media = {
|
|
30311
|
+
images: [
|
|
30312
|
+
...outputs.images.map((image, i) => ({
|
|
30313
|
+
url: image.url,
|
|
30314
|
+
alt: `Imagen ${i + 1}`
|
|
30315
|
+
})),
|
|
30316
|
+
...outputs.landing.sections.map((section) => ({
|
|
30317
|
+
url: section.url,
|
|
30318
|
+
alt: section.role
|
|
30319
|
+
}))
|
|
30320
|
+
],
|
|
30321
|
+
videos: outputs.videos.flatMap((video) => video.variants.map((variant) => ({
|
|
30322
|
+
url: variant.url,
|
|
30323
|
+
label: `${video.angleKey} \xB7 ${variant.kind}`,
|
|
30324
|
+
...video.scriptRewritten ? {
|
|
30325
|
+
scriptRewritten: true
|
|
30326
|
+
} : {}
|
|
30327
|
+
}))),
|
|
30328
|
+
links: []
|
|
30329
|
+
};
|
|
29925
30330
|
return {
|
|
30331
|
+
structuredContent: {
|
|
30332
|
+
...snapshot,
|
|
30333
|
+
outputs
|
|
30334
|
+
},
|
|
30335
|
+
_meta: {
|
|
30336
|
+
taskResults: buildTaskResultsView(media, proxyBaseUrl)
|
|
30337
|
+
},
|
|
29926
30338
|
content: [
|
|
29927
30339
|
{
|
|
29928
30340
|
type: "text",
|
|
@@ -29943,12 +30355,20 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
29943
30355
|
const detail = err instanceof Error ? err.stack ?? err.message : String(err);
|
|
29944
30356
|
process.stderr.write(`mcp get_task_status: fetchTaskOutputs failed for ${input.taskId}: ${detail}
|
|
29945
30357
|
`);
|
|
29946
|
-
return
|
|
30358
|
+
return {
|
|
30359
|
+
...asText(snapshot),
|
|
30360
|
+
_meta: {
|
|
30361
|
+
taskResults: {
|
|
30362
|
+
...statusMeta.taskResults,
|
|
30363
|
+
state: "error"
|
|
30364
|
+
}
|
|
30365
|
+
}
|
|
30366
|
+
};
|
|
29947
30367
|
}
|
|
29948
30368
|
} catch (e) {
|
|
29949
30369
|
throw translateError(e);
|
|
29950
30370
|
}
|
|
29951
|
-
});
|
|
30371
|
+
}));
|
|
29952
30372
|
server.registerTool("list_tasks", {
|
|
29953
30373
|
description: listTasksGuidance.summary + " \xDAsala para encontrar una tarea previa por nombre o revisar el historial antes de pedir un taskId. Soporta paginaci\xF3n con limit/offset y filtro de texto. No crea, reanuda ni modifica tareas.",
|
|
29954
30374
|
inputSchema: ListTasksInput.shape,
|
|
@@ -29961,16 +30381,16 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
29961
30381
|
if (input.search) qs.set("search", input.search);
|
|
29962
30382
|
const path3 = `/v1/tasks${qs.toString() ? "?" + qs.toString() : ""}`;
|
|
29963
30383
|
const r = await api.getJson(path3);
|
|
29964
|
-
const page =
|
|
29965
|
-
items:
|
|
30384
|
+
const page = z125.object({
|
|
30385
|
+
items: z125.array(z125.unknown())
|
|
29966
30386
|
}).passthrough().safeParse(r);
|
|
29967
30387
|
if (!page.success) return asText(r);
|
|
29968
30388
|
return asText({
|
|
29969
30389
|
...page.data,
|
|
29970
30390
|
items: page.data.items.map((item) => {
|
|
29971
|
-
const servicePage =
|
|
29972
|
-
taskId:
|
|
29973
|
-
resourceType:
|
|
30391
|
+
const servicePage = z125.object({
|
|
30392
|
+
taskId: z125.string().uuid(),
|
|
30393
|
+
resourceType: z125.literal("service_page")
|
|
29974
30394
|
}).passthrough().safeParse(item);
|
|
29975
30395
|
if (!servicePage.success) return item;
|
|
29976
30396
|
return {
|
|
@@ -30460,28 +30880,28 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
30460
30880
|
__name(registerTaskTools, "registerTaskTools");
|
|
30461
30881
|
|
|
30462
30882
|
// src/tools/brands.ts
|
|
30463
|
-
import { z as
|
|
30883
|
+
import { z as z126 } from "zod";
|
|
30464
30884
|
var guidance2 = getProductMakerCapabilityModelGuidance("create_brand");
|
|
30465
30885
|
var BRAND_START_REPLAY_WINDOW_MS = 15 * 60 * 1e3;
|
|
30466
30886
|
var BRAND_NOTES_MAX_CHARS = 2e4;
|
|
30467
30887
|
var BRAND_AMBIGUOUS_REQUEST_RETENTION_MS = 24 * 60 * 60 * 1e3;
|
|
30468
30888
|
var BRAND_CREATION_REQUEST_LIMIT = 500;
|
|
30469
30889
|
var brandCreationRequests = /* @__PURE__ */ new Map();
|
|
30470
|
-
var CreateBrandInput =
|
|
30471
|
-
action:
|
|
30890
|
+
var CreateBrandInput = z126.object({
|
|
30891
|
+
action: z126.enum([
|
|
30472
30892
|
"start",
|
|
30473
30893
|
"status",
|
|
30474
30894
|
"list"
|
|
30475
30895
|
]).default("start").describe("start cotiza (sin confirmed) o inicia (confirmed=true) el an\xE1lisis; status consulta brandId hasta ready o failed; list muestra las marcas que el usuario ya tiene."),
|
|
30476
|
-
sourceUrl:
|
|
30477
|
-
businessNotes:
|
|
30478
|
-
language:
|
|
30896
|
+
sourceUrl: z126.string().trim().min(1).max(BRAND_SOURCE_URL_MAX_LENGTH).optional().describe("Instagram, Facebook, TikTok o web p\xFAblica del negocio, como la dio el usuario (\xAB@sanlucasbarberia\xBB, \xABinstagram.com/sanlucasbarberia\xBB, \xABmibarberia.com\xBB). Obligatorio para start."),
|
|
30897
|
+
businessNotes: z126.string().trim().max(BRAND_NOTES_MAX_CHARS).optional().describe("Opcional. Lo que el usuario cuente de su negocio en el chat (servicios y precios, WhatsApp, ciudad o zona, horarios). Se guarda como documento del negocio y llega tal cual a la marca y a su landing. Copia sus palabras; no inventes datos."),
|
|
30898
|
+
language: z126.enum([
|
|
30479
30899
|
"es",
|
|
30480
30900
|
"en",
|
|
30481
30901
|
"pt"
|
|
30482
30902
|
]).optional().describe("Idioma de la conversaci\xF3n. Solo se usa si la p\xE1gina del negocio no deja claro su idioma."),
|
|
30483
|
-
confirmed:
|
|
30484
|
-
brandId:
|
|
30903
|
+
confirmed: z126.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio y que el usuario acepte. Sin confirmed, start solo cotiza y no cobra."),
|
|
30904
|
+
brandId: z126.string().uuid().optional().describe("ID de la marca. Obligatorio para status; no lo inventes.")
|
|
30485
30905
|
}).strict();
|
|
30486
30906
|
function normalizeBrandSourceUrl(raw) {
|
|
30487
30907
|
const value = raw.trim();
|
|
@@ -30765,24 +31185,24 @@ __name(registerBrandTools, "registerBrandTools");
|
|
|
30765
31185
|
|
|
30766
31186
|
// src/tools/service-landing.ts
|
|
30767
31187
|
import { createHash as createHash4, randomUUID } from "crypto";
|
|
30768
|
-
import { z as
|
|
31188
|
+
import { z as z127 } from "zod";
|
|
30769
31189
|
var guidance3 = getProductMakerCapabilityModelGuidance("create_service_landing");
|
|
30770
31190
|
var SERVICE_LANDING_KEY_NAMESPACE = "6f1d8c2a-3b4e-5f60-8a7b-9c0d1e2f3a4b";
|
|
30771
31191
|
var SERVICE_LANDING_INFO_MAX_CHARS = 2e4;
|
|
30772
|
-
var CreateServiceLandingInput =
|
|
30773
|
-
action:
|
|
31192
|
+
var CreateServiceLandingInput = z127.object({
|
|
31193
|
+
action: z127.enum([
|
|
30774
31194
|
"prepare",
|
|
30775
31195
|
"build",
|
|
30776
31196
|
"status",
|
|
30777
31197
|
"publish"
|
|
30778
31198
|
]).default("prepare").describe("prepare (gratis) crea o retoma la landing de la marca y da el precio; build (pagado, confirmed=true) genera la p\xE1gina directamente con la marca y los datos guardados; status sigue el avance; publish la publica y devuelve su enlace."),
|
|
30779
|
-
brandId:
|
|
30780
|
-
servicePageId:
|
|
30781
|
-
businessInfo:
|
|
30782
|
-
confirmed:
|
|
30783
|
-
maxCredits:
|
|
30784
|
-
operationId:
|
|
30785
|
-
slug:
|
|
31199
|
+
brandId: z127.string().uuid().optional().describe("ID de la marca (de create_brand). Obligatorio para prepare. Nunca un taskId de producto."),
|
|
31200
|
+
servicePageId: z127.string().uuid().optional().describe("ID de la landing que devolvi\xF3 prepare. Obligatorio para build, status y publish."),
|
|
31201
|
+
businessInfo: z127.string().trim().max(SERVICE_LANDING_INFO_MAX_CHARS).optional().describe("Opcional. Lo que el usuario cont\xF3 del negocio y no estaba en su marca: servicios y precios, WhatsApp o tel\xE9fono, ciudad o zona, horarios. Copia sus palabras; no inventes datos."),
|
|
31202
|
+
confirmed: z127.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio total y que el usuario acepte. Obligatorio para build."),
|
|
31203
|
+
maxCredits: z127.number().int().positive().optional().describe("El total en cr\xE9ditos que el usuario acept\xF3 (el que devolvi\xF3 prepare). Obligatorio para build: ninguna etapa se inicia si su precio supera este total."),
|
|
31204
|
+
operationId: z127.string().uuid().optional().describe("Opcional en status: la operaci\xF3n que devolvi\xF3 build."),
|
|
31205
|
+
slug: z127.string().trim().toLowerCase().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).max(64).optional().describe("Opcional en publish: la direcci\xF3n corta de la p\xE1gina (ej. sanlucas-barberia). Si falta se usa la sugerida desde el nombre del negocio.")
|
|
30786
31206
|
}).strict();
|
|
30787
31207
|
function serviceKey(...parts) {
|
|
30788
31208
|
return deriveUuidV5(parts.join(":"), SERVICE_LANDING_KEY_NAMESPACE);
|
|
@@ -31015,7 +31435,7 @@ function registerServiceLandingTools(server, api) {
|
|
|
31015
31435
|
const build = quoteRange(generationQuote);
|
|
31016
31436
|
const totalMin = build.min;
|
|
31017
31437
|
const totalCredits = build.max;
|
|
31018
|
-
const requiredBalanceCredits =
|
|
31438
|
+
const requiredBalanceCredits = totalCredits;
|
|
31019
31439
|
const askFor = page2.facts.contact.channels.some((channel) => channel.kind === "whatsapp") ? "su ciudad o zona y sus servicios con precio (su WhatsApp ya viene de la marca: no lo pidas)" : "su WhatsApp o tel\xE9fono, su ciudad o zona y sus servicios con precio";
|
|
31020
31440
|
const priceText = totalMin === totalCredits ? `${totalCredits} cr\xE9ditos` : `entre ${totalMin} y ${totalCredits} cr\xE9ditos`;
|
|
31021
31441
|
return asText({
|
|
@@ -31032,7 +31452,7 @@ function registerServiceLandingTools(server, api) {
|
|
|
31032
31452
|
totalCredits,
|
|
31033
31453
|
requiredBalanceCredits
|
|
31034
31454
|
},
|
|
31035
|
-
nextAction: `En un solo mensaje: dile al usuario que crear su landing cuesta ${priceText} en total (se cobra lo que se use; necesita al menos ${requiredBalanceCredits} cr\xE9ditos de saldo para empezar) y preg\xFAntale, solo si no lo dijo ya en esta conversaci\xF3n, ${askFor} (puede omitirlo). Cuando acepte el precio, llama action=build con servicePageId=${page2.id}, confirmed=true, maxCredits=${totalCredits} y businessInfo con lo que respondi\xF3.`
|
|
31455
|
+
nextAction: `En un solo mensaje: dile al usuario que crear su landing cuesta ${priceText} en total (se cobra lo que se use; necesita al menos ${requiredBalanceCredits} cr\xE9ditos de saldo para empezar) y preg\xFAntale, solo si no lo dijo ya en esta conversaci\xF3n, ${askFor} (puede omitirlo). prepare no consulta el saldo: no interpretes un saldo desconocido como insuficiente ni exijas una comprobaci\xF3n manual. Cuando acepte el precio, llama action=build con servicePageId=${page2.id}, confirmed=true, maxCredits=${totalCredits} y businessInfo con lo que respondi\xF3; comunica cualquier rechazo que devuelva el servidor.`
|
|
31036
31456
|
});
|
|
31037
31457
|
}
|
|
31038
31458
|
if (!input.servicePageId) {
|
|
@@ -31157,7 +31577,7 @@ function registerServiceLandingTools(server, api) {
|
|
|
31157
31577
|
__name(registerServiceLandingTools, "registerServiceLandingTools");
|
|
31158
31578
|
|
|
31159
31579
|
// src/tools/service-images.ts
|
|
31160
|
-
import { z as
|
|
31580
|
+
import { z as z128 } from "zod";
|
|
31161
31581
|
var guidance4 = getProductMakerCapabilityModelGuidance("create_service_images");
|
|
31162
31582
|
var SERVICE_IMAGE_FORMATS = [
|
|
31163
31583
|
"4:5",
|
|
@@ -31170,23 +31590,23 @@ var LANGUAGE_TAGS = {
|
|
|
31170
31590
|
en: "en-US",
|
|
31171
31591
|
pt: "pt-BR"
|
|
31172
31592
|
};
|
|
31173
|
-
var CreateServiceImagesInput =
|
|
31174
|
-
brandId:
|
|
31175
|
-
instruction:
|
|
31176
|
-
delegateToAi:
|
|
31177
|
-
format:
|
|
31178
|
-
count:
|
|
31179
|
-
quality:
|
|
31593
|
+
var CreateServiceImagesInput = z128.object({
|
|
31594
|
+
brandId: z128.string().uuid().optional().describe("ID de un servicio propio y listo (de create_brand), obligatorio para cotizar y crear im\xE1genes nuevas. En un retry hist\xF3rico ya confirmado que originalmente no ten\xEDa este campo, conserva la petici\xF3n original. Nunca un taskId de producto."),
|
|
31595
|
+
instruction: z128.string().trim().max(4e3).optional().describe("Opcional. Qu\xE9 servicio o promoci\xF3n mostrar, con las palabras del usuario (ej. \xABcorte + barba a $35.000 los martes\xBB). Si se omite, la IA propone la imagen usando la informaci\xF3n del servicio."),
|
|
31596
|
+
delegateToAi: z128.boolean().optional().describe("true si el usuario prefiere que la IA elija qu\xE9 mostrar a partir de su servicio. Tambi\xE9n se delega cuando instruction est\xE1 vac\xEDo."),
|
|
31597
|
+
format: z128.enum(SERVICE_IMAGE_FORMATS).optional().describe('Formato: "4:5" (feed, por defecto), "9:16" (historias/reels) o "1:1" (cuadrado).'),
|
|
31598
|
+
count: z128.number().int().min(1).max(SERVICE_IMAGE_MAX_COUNT).optional().describe("Cu\xE1ntas im\xE1genes, de 1 a 3 (por defecto 1)."),
|
|
31599
|
+
quality: z128.enum([
|
|
31180
31600
|
"standard",
|
|
31181
31601
|
"high"
|
|
31182
31602
|
]).optional().describe('Calidad: "standard" (por defecto) o "high" (m\xE1s cara; no disponible en 4:5).'),
|
|
31183
|
-
language:
|
|
31603
|
+
language: z128.enum([
|
|
31184
31604
|
"es",
|
|
31185
31605
|
"en",
|
|
31186
31606
|
"pt"
|
|
31187
31607
|
]).optional().describe("Idioma de los textos de la imagen (por defecto es)."),
|
|
31188
|
-
adCopy:
|
|
31189
|
-
confirmed:
|
|
31608
|
+
adCopy: z128.boolean().optional().describe("Compatibilidad con clientes anteriores: el copy para publicar siempre est\xE1 incluido en cada imagen de servicios."),
|
|
31609
|
+
confirmed: z128.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio y que el usuario acepte. Sin confirmed, solo cotiza y no cobra.")
|
|
31190
31610
|
}).strict();
|
|
31191
31611
|
function serviceImageModel(quality) {
|
|
31192
31612
|
return quality === "high" ? AD_CREATIVE_MODELS.PREMIUM : AD_CREATIVE_MODELS.STANDARD;
|
|
@@ -31300,10 +31720,10 @@ function registerServiceImageTools(server, api, options = {}) {
|
|
|
31300
31720
|
...priceCredits ? {
|
|
31301
31721
|
priceCredits
|
|
31302
31722
|
} : {},
|
|
31303
|
-
nextAction: "Dile al usuario que est\xE1s creando sus im\xE1genes. Llama get_task_status con este taskId (waitSeconds=45) hasta done (trae las im\xE1genes) o error."
|
|
31723
|
+
nextAction: "Dile al usuario que est\xE1s creando sus im\xE1genes. Llama get_task_status con este taskId (waitSeconds=45) hasta done (trae las im\xE1genes reales de ProductMaker) o error. Muestra los recursos de imagen devueltos directamente en el chat. Nunca generes ni recrees una imagen sustituta con otra herramienta. Si la vista previa falla, explica el fallo y conserva los enlaces protegidos devueltos."
|
|
31304
31724
|
});
|
|
31305
31725
|
} catch (error) {
|
|
31306
|
-
if (error instanceof
|
|
31726
|
+
if (error instanceof z128.ZodError) throw invalidInputFromZod(error);
|
|
31307
31727
|
throw translateError(error);
|
|
31308
31728
|
}
|
|
31309
31729
|
});
|
|
@@ -31311,7 +31731,7 @@ function registerServiceImageTools(server, api, options = {}) {
|
|
|
31311
31731
|
__name(registerServiceImageTools, "registerServiceImageTools");
|
|
31312
31732
|
|
|
31313
31733
|
// src/tools/creatives.ts
|
|
31314
|
-
import { z as
|
|
31734
|
+
import { z as z129 } from "zod";
|
|
31315
31735
|
var generateFreeVideoGuidance = getProductMakerCapabilityModelGuidance("generate_free_video");
|
|
31316
31736
|
var generateVideoCreativeGuidance = getProductMakerCapabilityModelGuidance("generate_video_creative");
|
|
31317
31737
|
var generateImageCreativesGuidance = getProductMakerCapabilityModelGuidance("generate_image_creatives");
|
|
@@ -31322,72 +31742,72 @@ var CreativeRefs = {
|
|
|
31322
31742
|
images: ImagesInput,
|
|
31323
31743
|
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.'),
|
|
31324
31744
|
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.'),
|
|
31325
|
-
price:
|
|
31326
|
-
offer:
|
|
31327
|
-
compareAtPrice:
|
|
31328
|
-
productContext:
|
|
31329
|
-
productLabel:
|
|
31330
|
-
buyerPersona:
|
|
31331
|
-
isCombo:
|
|
31332
|
-
competitorScanEnabled:
|
|
31333
|
-
brandId:
|
|
31745
|
+
price: z129.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.'),
|
|
31746
|
+
offer: z129.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.'),
|
|
31747
|
+
compareAtPrice: z129.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
|
|
31748
|
+
productContext: z129.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."),
|
|
31749
|
+
productLabel: z129.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.'),
|
|
31750
|
+
buyerPersona: z129.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.'),
|
|
31751
|
+
isCombo: z129.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
|
|
31752
|
+
competitorScanEnabled: z129.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."),
|
|
31753
|
+
brandId: z129.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.")
|
|
31334
31754
|
};
|
|
31335
|
-
var VideoPresenter =
|
|
31336
|
-
|
|
31337
|
-
mode:
|
|
31755
|
+
var VideoPresenter = z129.discriminatedUnion("mode", [
|
|
31756
|
+
z129.object({
|
|
31757
|
+
mode: z129.literal("none")
|
|
31338
31758
|
}).strict(),
|
|
31339
|
-
|
|
31340
|
-
mode:
|
|
31341
|
-
actorId:
|
|
31759
|
+
z129.object({
|
|
31760
|
+
mode: z129.literal("saved_actor"),
|
|
31761
|
+
actorId: z129.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
|
|
31342
31762
|
}).strict(),
|
|
31343
|
-
|
|
31344
|
-
mode:
|
|
31345
|
-
description:
|
|
31763
|
+
z129.object({
|
|
31764
|
+
mode: z129.literal("described"),
|
|
31765
|
+
description: z129.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
|
|
31346
31766
|
}).strict()
|
|
31347
31767
|
]);
|
|
31348
|
-
var VideoCreativeSetup =
|
|
31349
|
-
|
|
31350
|
-
mode:
|
|
31768
|
+
var VideoCreativeSetup = z129.discriminatedUnion("mode", [
|
|
31769
|
+
z129.object({
|
|
31770
|
+
mode: z129.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
|
|
31351
31771
|
}).strict(),
|
|
31352
|
-
|
|
31353
|
-
mode:
|
|
31772
|
+
z129.object({
|
|
31773
|
+
mode: z129.literal("guided"),
|
|
31354
31774
|
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.'),
|
|
31355
|
-
buyerPersona:
|
|
31775
|
+
buyerPersona: z129.string().trim().min(1).max(360),
|
|
31356
31776
|
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.'),
|
|
31357
31777
|
presenter: VideoPresenter,
|
|
31358
|
-
creativeDirection:
|
|
31778
|
+
creativeDirection: z129.string().trim().min(1).max(500).nullable().describe("Direcci\xF3n visual elegida. null significa que el usuario deleg\xF3 expl\xEDcitamente esta decisi\xF3n.")
|
|
31359
31779
|
}).strict()
|
|
31360
31780
|
]);
|
|
31361
|
-
var VideoInput =
|
|
31781
|
+
var VideoInput = z129.object({
|
|
31362
31782
|
images: CreativeRefs.images.optional(),
|
|
31363
31783
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
31364
|
-
title:
|
|
31365
|
-
primaryAngle:
|
|
31784
|
+
title: z129.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
|
|
31785
|
+
primaryAngle: z129.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".'),
|
|
31366
31786
|
language: CreativeRefs.language,
|
|
31367
31787
|
country: CreativeRefs.country,
|
|
31368
|
-
aspectRatio:
|
|
31788
|
+
aspectRatio: z129.enum([
|
|
31369
31789
|
"9:16",
|
|
31370
31790
|
"16:9",
|
|
31371
31791
|
"Auto"
|
|
31372
31792
|
]).describe('Relaci\xF3n de aspecto. "9:16" = vertical (TikTok/Reels \u2014 default recomendado para ads). "16:9" = horizontal (YouTube). "Auto" = decide la IA.'),
|
|
31373
31793
|
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.'),
|
|
31374
|
-
durationSeconds:
|
|
31375
|
-
videoAngleCount:
|
|
31794
|
+
durationSeconds: z129.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."),
|
|
31795
|
+
videoAngleCount: z129.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."),
|
|
31376
31796
|
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.'),
|
|
31377
31797
|
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."),
|
|
31378
31798
|
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.'),
|
|
31379
31799
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El sistema elige el proveedor internamente. Default: economy.'),
|
|
31380
31800
|
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.'),
|
|
31381
|
-
features:
|
|
31801
|
+
features: z129.array(z129.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
|
|
31382
31802
|
price: CreativeRefs.price,
|
|
31383
31803
|
offer: CreativeRefs.offer,
|
|
31384
31804
|
productContext: CreativeRefs.productContext,
|
|
31385
31805
|
productLabel: CreativeRefs.productLabel,
|
|
31386
|
-
cta:
|
|
31387
|
-
scriptNotes:
|
|
31806
|
+
cta: z129.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.'),
|
|
31807
|
+
scriptNotes: z129.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.'),
|
|
31388
31808
|
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.'),
|
|
31389
31809
|
competitorScanEnabled: CreativeRefs.competitorScanEnabled,
|
|
31390
|
-
replicateWinnerWhenFound:
|
|
31810
|
+
replicateWinnerWhenFound: z129.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."),
|
|
31391
31811
|
brandId: CreativeRefs.brandId
|
|
31392
31812
|
}).strict();
|
|
31393
31813
|
var FreeVideoQualityEnum = VideoQualityEnum;
|
|
@@ -31405,7 +31825,7 @@ var FREE_VIDEO_DURATIONS_BY_QUALITY = {
|
|
|
31405
31825
|
length: 29
|
|
31406
31826
|
}, (_, index) => index + 2)
|
|
31407
31827
|
};
|
|
31408
|
-
var FreeVideoModelIdEnum =
|
|
31828
|
+
var FreeVideoModelIdEnum = z129.enum([
|
|
31409
31829
|
"grok-imagine-video-1-5-preview",
|
|
31410
31830
|
"minimax-h3/reference-to-video",
|
|
31411
31831
|
"wan/3-0-video",
|
|
@@ -31416,66 +31836,66 @@ var FREE_SELECTABLE_MODEL_IDS = [
|
|
|
31416
31836
|
"minimax-h3/reference-to-video",
|
|
31417
31837
|
"wan/3-0-video"
|
|
31418
31838
|
];
|
|
31419
|
-
var FreeVideoInput =
|
|
31839
|
+
var FreeVideoInput = z129.object({
|
|
31420
31840
|
images: ImagesInput.optional().describe("Opcional. 1-5 fotos del producto. Om\xEDtelo para generar desde texto puro."),
|
|
31421
|
-
rawPrompt:
|
|
31841
|
+
rawPrompt: z129.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."),
|
|
31422
31842
|
language: CreativeRefs.language,
|
|
31423
31843
|
quality: FreeVideoQualityEnum.describe('Calidad del video: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan).'),
|
|
31424
31844
|
// Retired in MCP 7.0.0 (Task 11): kept in the schema, accepted, and
|
|
31425
31845
|
// parsed ONLY so the handler can reject it with a message naming its
|
|
31426
31846
|
// replacement — dropping it silently would turn a caller's explicit
|
|
31427
31847
|
// Pro++ pick into a quiet fallback to Wan.
|
|
31428
|
-
freeProModel:
|
|
31848
|
+
freeProModel: z129.enum([
|
|
31429
31849
|
"wan",
|
|
31430
31850
|
"seedance"
|
|
31431
31851
|
]).optional().describe("ELIMINADO en MCP 7.0.0 \u2014 usa `modelId`. Enviar este campo produce un error."),
|
|
31432
31852
|
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.'),
|
|
31433
|
-
durationSeconds:
|
|
31853
|
+
durationSeconds: z129.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."),
|
|
31434
31854
|
videoResolution: VideoResolutionEnum.describe("Resoluci\xF3n del video: 480p o 720p."),
|
|
31435
|
-
generateAiMusic:
|
|
31855
|
+
generateAiMusic: z129.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.'),
|
|
31436
31856
|
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.'),
|
|
31437
|
-
addSubtitles:
|
|
31438
|
-
idempotencyKey:
|
|
31857
|
+
addSubtitles: z129.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
|
|
31858
|
+
idempotencyKey: z129.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.")
|
|
31439
31859
|
}).strict();
|
|
31440
31860
|
var imageStyleList = ImageCreativeStyleEnum.options.join(" | ");
|
|
31441
|
-
var ImageCreativeSetup =
|
|
31442
|
-
|
|
31443
|
-
mode:
|
|
31861
|
+
var ImageCreativeSetup = z129.discriminatedUnion("mode", [
|
|
31862
|
+
z129.object({
|
|
31863
|
+
mode: z129.literal("automatic")
|
|
31444
31864
|
}).strict(),
|
|
31445
|
-
|
|
31446
|
-
mode:
|
|
31447
|
-
creativeArchetype:
|
|
31865
|
+
z129.object({
|
|
31866
|
+
mode: z129.literal("guided"),
|
|
31867
|
+
creativeArchetype: z129.union([
|
|
31448
31868
|
ImageCreativeArchetypeEnum,
|
|
31449
|
-
|
|
31869
|
+
z129.literal("ai_decides")
|
|
31450
31870
|
]),
|
|
31451
|
-
visualTreatment:
|
|
31871
|
+
visualTreatment: z129.union([
|
|
31452
31872
|
ImageCreativeVisualTreatmentEnum,
|
|
31453
|
-
|
|
31873
|
+
z129.literal("ai_decides")
|
|
31454
31874
|
]),
|
|
31455
31875
|
aspectRatio: ImageCreativeAspectRatioEnum,
|
|
31456
|
-
nVariants:
|
|
31457
|
-
|
|
31458
|
-
|
|
31459
|
-
|
|
31460
|
-
|
|
31461
|
-
|
|
31876
|
+
nVariants: z129.union([
|
|
31877
|
+
z129.literal(1),
|
|
31878
|
+
z129.literal(2),
|
|
31879
|
+
z129.literal(3),
|
|
31880
|
+
z129.literal(4),
|
|
31881
|
+
z129.literal(6)
|
|
31462
31882
|
]),
|
|
31463
|
-
imageModel:
|
|
31464
|
-
styleMix:
|
|
31465
|
-
generateAdCopy:
|
|
31466
|
-
competitorScanEnabled:
|
|
31467
|
-
productContext:
|
|
31468
|
-
creativeDirection:
|
|
31469
|
-
brandColors:
|
|
31470
|
-
headline:
|
|
31471
|
-
subheadline:
|
|
31883
|
+
imageModel: z129.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.'),
|
|
31884
|
+
styleMix: z129.boolean().nullable().describe("Decisi\xF3n s\xF3lo para 2\u20134 variantes. Usa null para 1 o 6, cuando la UI no hace esta pregunta."),
|
|
31885
|
+
generateAdCopy: z129.boolean(),
|
|
31886
|
+
competitorScanEnabled: z129.boolean(),
|
|
31887
|
+
productContext: z129.string().trim().min(1).max(3e3).nullable(),
|
|
31888
|
+
creativeDirection: z129.string().trim().min(1).max(500).nullable(),
|
|
31889
|
+
brandColors: z129.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.'),
|
|
31890
|
+
headline: z129.string().trim().min(1).max(120).nullable(),
|
|
31891
|
+
subheadline: z129.string().trim().min(1).max(160).nullable()
|
|
31472
31892
|
}).strict()
|
|
31473
31893
|
]).superRefine((setup, context) => {
|
|
31474
31894
|
if (setup.mode !== "guided") return;
|
|
31475
31895
|
const needsStyleMix = setup.nVariants >= 2 && setup.nVariants <= 4;
|
|
31476
31896
|
if (needsStyleMix && setup.styleMix === null) {
|
|
31477
31897
|
context.addIssue({
|
|
31478
|
-
code:
|
|
31898
|
+
code: z129.ZodIssueCode.custom,
|
|
31479
31899
|
path: [
|
|
31480
31900
|
"styleMix"
|
|
31481
31901
|
],
|
|
@@ -31484,7 +31904,7 @@ var ImageCreativeSetup = z128.discriminatedUnion("mode", [
|
|
|
31484
31904
|
}
|
|
31485
31905
|
if (!needsStyleMix && setup.styleMix !== null) {
|
|
31486
31906
|
context.addIssue({
|
|
31487
|
-
code:
|
|
31907
|
+
code: z129.ZodIssueCode.custom,
|
|
31488
31908
|
path: [
|
|
31489
31909
|
"styleMix"
|
|
31490
31910
|
],
|
|
@@ -31493,7 +31913,7 @@ var ImageCreativeSetup = z128.discriminatedUnion("mode", [
|
|
|
31493
31913
|
}
|
|
31494
31914
|
if (imageResolutionOf(setup.imageModel) === "2k" && setup.aspectRatio === "4:5") {
|
|
31495
31915
|
context.addIssue({
|
|
31496
|
-
code:
|
|
31916
|
+
code: z129.ZodIssueCode.custom,
|
|
31497
31917
|
path: [
|
|
31498
31918
|
"aspectRatio"
|
|
31499
31919
|
],
|
|
@@ -31501,55 +31921,55 @@ var ImageCreativeSetup = z128.discriminatedUnion("mode", [
|
|
|
31501
31921
|
});
|
|
31502
31922
|
}
|
|
31503
31923
|
});
|
|
31504
|
-
var LandingCreativeSetup =
|
|
31505
|
-
|
|
31506
|
-
mode:
|
|
31924
|
+
var LandingCreativeSetup = z129.discriminatedUnion("mode", [
|
|
31925
|
+
z129.object({
|
|
31926
|
+
mode: z129.literal("automatic")
|
|
31507
31927
|
}).strict(),
|
|
31508
|
-
|
|
31509
|
-
mode:
|
|
31928
|
+
z129.object({
|
|
31929
|
+
mode: z129.literal("guided"),
|
|
31510
31930
|
landingStrategy: LandingStrategyEnum,
|
|
31511
31931
|
landingImageFormat: LandingImageFormatEnum,
|
|
31512
|
-
competitorScanEnabled:
|
|
31513
|
-
paymentMethods:
|
|
31514
|
-
productContext:
|
|
31515
|
-
creativeDirection:
|
|
31516
|
-
headline:
|
|
31517
|
-
subheadline:
|
|
31932
|
+
competitorScanEnabled: z129.boolean(),
|
|
31933
|
+
paymentMethods: z129.string().trim().min(1).max(240).nullable(),
|
|
31934
|
+
productContext: z129.string().trim().min(1).max(3e3).nullable(),
|
|
31935
|
+
creativeDirection: z129.string().trim().min(1).max(500).nullable(),
|
|
31936
|
+
headline: z129.string().trim().min(1).max(120).nullable(),
|
|
31937
|
+
subheadline: z129.string().trim().min(1).max(160).nullable()
|
|
31518
31938
|
}).strict()
|
|
31519
31939
|
]);
|
|
31520
|
-
var ImageInput =
|
|
31940
|
+
var ImageInput = z129.object({
|
|
31521
31941
|
images: CreativeRefs.images.optional(),
|
|
31522
31942
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
31523
|
-
productTitle:
|
|
31524
|
-
primaryAngle:
|
|
31943
|
+
productTitle: z129.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
|
|
31944
|
+
primaryAngle: z129.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.'),
|
|
31525
31945
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
31526
31946
|
language: CreativeRefs.language,
|
|
31527
31947
|
country: CreativeRefs.country,
|
|
31528
31948
|
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."),
|
|
31529
31949
|
imageStyle: ImageCreativeStyleEnum.optional().describe(`Opcional. Estilo del shot del producto. Valores: ${imageStyleList}. Si se omite, la IA escoge seg\xFAn el archetype.`),
|
|
31530
|
-
features:
|
|
31950
|
+
features: z129.array(z129.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
|
|
31531
31951
|
price: CreativeRefs.price,
|
|
31532
|
-
omitPrice:
|
|
31952
|
+
omitPrice: z129.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."),
|
|
31533
31953
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
31534
31954
|
offer: CreativeRefs.offer,
|
|
31535
31955
|
productLabel: CreativeRefs.productLabel,
|
|
31536
31956
|
isCombo: CreativeRefs.isCombo,
|
|
31537
31957
|
brandId: CreativeRefs.brandId
|
|
31538
31958
|
});
|
|
31539
|
-
var EditImageCreativeInput =
|
|
31540
|
-
taskId:
|
|
31541
|
-
variantIndex:
|
|
31542
|
-
clientRequestId:
|
|
31543
|
-
instruction:
|
|
31959
|
+
var EditImageCreativeInput = z129.object({
|
|
31960
|
+
taskId: z129.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
|
|
31961
|
+
variantIndex: z129.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
|
|
31962
|
+
clientRequestId: z129.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."),
|
|
31963
|
+
instruction: z129.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".')
|
|
31544
31964
|
});
|
|
31545
|
-
var LandingInput =
|
|
31546
|
-
includeInitialLandingGif:
|
|
31965
|
+
var LandingInput = z129.object({
|
|
31966
|
+
includeInitialLandingGif: z129.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."),
|
|
31547
31967
|
images: CreativeRefs.images.optional(),
|
|
31548
31968
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
31549
31969
|
language: CreativeRefs.language,
|
|
31550
31970
|
country: CreativeRefs.country,
|
|
31551
31971
|
creativeSetup: LandingCreativeSetup.describe("Configuraci\xF3n obligatoria de landing cl\xE1sica equivalente al wizard web. No expone landing editable/code mientras siga siendo admin-only."),
|
|
31552
|
-
salesAngle:
|
|
31972
|
+
salesAngle: z129.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.'),
|
|
31553
31973
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
31554
31974
|
price: CreativeRefs.price,
|
|
31555
31975
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
@@ -31831,8 +32251,8 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
31831
32251
|
server.registerTool("get_image_edit_status", {
|
|
31832
32252
|
description: imageEditStatusGuidance.summary,
|
|
31833
32253
|
inputSchema: {
|
|
31834
|
-
taskId:
|
|
31835
|
-
operationId:
|
|
32254
|
+
taskId: z129.string().uuid(),
|
|
32255
|
+
operationId: z129.string().uuid()
|
|
31836
32256
|
},
|
|
31837
32257
|
annotations: READS_INTERNAL
|
|
31838
32258
|
}, async (input) => {
|
|
@@ -31889,10 +32309,10 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
31889
32309
|
__name(registerCreativeTools, "registerCreativeTools");
|
|
31890
32310
|
|
|
31891
32311
|
// src/tools/creative-variants.ts
|
|
31892
|
-
import { z as
|
|
32312
|
+
import { z as z130 } from "zod";
|
|
31893
32313
|
var estimateCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("estimate_creative_variant");
|
|
31894
32314
|
var createCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("create_creative_variant");
|
|
31895
|
-
var LandingSectionKeyEnum =
|
|
32315
|
+
var LandingSectionKeyEnum = z130.enum([
|
|
31896
32316
|
"problem_hook",
|
|
31897
32317
|
"problem_cost",
|
|
31898
32318
|
"solution_mechanism",
|
|
@@ -31932,24 +32352,24 @@ var LandingSectionKeyEnum = z129.enum([
|
|
|
31932
32352
|
"lifestyle_fit",
|
|
31933
32353
|
"join_lifestyle"
|
|
31934
32354
|
]);
|
|
31935
|
-
var CreativeVariantKindEnum =
|
|
32355
|
+
var CreativeVariantKindEnum = z130.enum([
|
|
31936
32356
|
"video",
|
|
31937
32357
|
"image",
|
|
31938
32358
|
"landing"
|
|
31939
32359
|
]);
|
|
31940
|
-
var EstimateCreativeVariantInputBase =
|
|
31941
|
-
sourceTaskId:
|
|
32360
|
+
var EstimateCreativeVariantInputBase = z130.object({
|
|
32361
|
+
sourceTaskId: z130.string().uuid().describe("ID de la tarea original completada."),
|
|
31942
32362
|
kind: CreativeVariantKindEnum,
|
|
31943
32363
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Solo cambia el preset p\xFAblico; el servidor conserva el modelo/tier del task origen."),
|
|
31944
32364
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video. Resoluci\xF3n del nuevo render."),
|
|
31945
|
-
nVariants:
|
|
32365
|
+
nVariants: z130.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
31946
32366
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si ya conoces la secci\xF3n, evita cotizar la clasificaci\xF3n con IA."),
|
|
31947
|
-
instructions:
|
|
32367
|
+
instructions: z130.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.")
|
|
31948
32368
|
}).strict();
|
|
31949
32369
|
var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
31950
32370
|
if (input.kind === "video" && input.nVariants !== void 0) {
|
|
31951
32371
|
ctx.addIssue({
|
|
31952
|
-
code:
|
|
32372
|
+
code: z130.ZodIssueCode.custom,
|
|
31953
32373
|
path: [
|
|
31954
32374
|
"nVariants"
|
|
31955
32375
|
],
|
|
@@ -31959,7 +32379,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
31959
32379
|
if (input.kind !== "video") {
|
|
31960
32380
|
if (input.videoPreset !== void 0) {
|
|
31961
32381
|
ctx.addIssue({
|
|
31962
|
-
code:
|
|
32382
|
+
code: z130.ZodIssueCode.custom,
|
|
31963
32383
|
path: [
|
|
31964
32384
|
"videoPreset"
|
|
31965
32385
|
],
|
|
@@ -31968,7 +32388,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
31968
32388
|
}
|
|
31969
32389
|
if (input.videoResolution !== void 0) {
|
|
31970
32390
|
ctx.addIssue({
|
|
31971
|
-
code:
|
|
32391
|
+
code: z130.ZodIssueCode.custom,
|
|
31972
32392
|
path: [
|
|
31973
32393
|
"videoResolution"
|
|
31974
32394
|
],
|
|
@@ -31978,7 +32398,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
31978
32398
|
}
|
|
31979
32399
|
if (input.kind !== "image" && input.nVariants !== void 0) {
|
|
31980
32400
|
ctx.addIssue({
|
|
31981
|
-
code:
|
|
32401
|
+
code: z130.ZodIssueCode.custom,
|
|
31982
32402
|
path: [
|
|
31983
32403
|
"nVariants"
|
|
31984
32404
|
],
|
|
@@ -31988,7 +32408,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
31988
32408
|
if (input.kind !== "landing") {
|
|
31989
32409
|
if (input.sectionKey !== void 0) {
|
|
31990
32410
|
ctx.addIssue({
|
|
31991
|
-
code:
|
|
32411
|
+
code: z130.ZodIssueCode.custom,
|
|
31992
32412
|
path: [
|
|
31993
32413
|
"sectionKey"
|
|
31994
32414
|
],
|
|
@@ -31997,7 +32417,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
31997
32417
|
}
|
|
31998
32418
|
if (input.instructions !== void 0) {
|
|
31999
32419
|
ctx.addIssue({
|
|
32000
|
-
code:
|
|
32420
|
+
code: z130.ZodIssueCode.custom,
|
|
32001
32421
|
path: [
|
|
32002
32422
|
"instructions"
|
|
32003
32423
|
],
|
|
@@ -32006,31 +32426,31 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
32006
32426
|
}
|
|
32007
32427
|
}
|
|
32008
32428
|
});
|
|
32009
|
-
var CreateCreativeVariantInputBase =
|
|
32010
|
-
sourceTaskId:
|
|
32429
|
+
var CreateCreativeVariantInputBase = z130.object({
|
|
32430
|
+
sourceTaskId: z130.string().uuid().describe("ID de la tarea original completada."),
|
|
32011
32431
|
kind: CreativeVariantKindEnum,
|
|
32012
|
-
confirm:
|
|
32013
|
-
clientRequestId:
|
|
32014
|
-
angle:
|
|
32015
|
-
buyerPersona:
|
|
32016
|
-
scriptNotes:
|
|
32017
|
-
creativeDirection:
|
|
32432
|
+
confirm: z130.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
|
|
32433
|
+
clientRequestId: z130.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."),
|
|
32434
|
+
angle: z130.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
|
|
32435
|
+
buyerPersona: z130.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
|
|
32436
|
+
scriptNotes: z130.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
|
|
32437
|
+
creativeDirection: z130.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
|
|
32018
32438
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Preset p\xFAblico; el servidor resuelve modelo/tier desde el task origen."),
|
|
32019
32439
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video."),
|
|
32020
|
-
generateAiMusic:
|
|
32021
|
-
nVariants:
|
|
32440
|
+
generateAiMusic: z130.boolean().optional().describe("Opcional para video."),
|
|
32441
|
+
nVariants: z130.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
32022
32442
|
imageStyle: ImageCreativeStyleEnum.optional().describe("Opcional para imagen."),
|
|
32023
32443
|
creativeArchetype: ImageCreativeArchetypeEnum.optional().describe("Opcional para imagen."),
|
|
32024
32444
|
visualTreatment: ImageCreativeVisualTreatmentEnum.optional().describe("Opcional para imagen."),
|
|
32025
32445
|
aspectRatio: ImageCreativeAspectRatioEnum.optional().describe("Opcional para imagen."),
|
|
32026
|
-
styleMix:
|
|
32446
|
+
styleMix: z130.boolean().optional().describe("Opcional para imagen."),
|
|
32027
32447
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si se omite, se clasifica con IA a partir de instructions."),
|
|
32028
|
-
instructions:
|
|
32448
|
+
instructions: z130.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.")
|
|
32029
32449
|
}).strict();
|
|
32030
32450
|
var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
32031
32451
|
if ((input.kind === "video" || input.kind === "image") && !input.angle) {
|
|
32032
32452
|
ctx.addIssue({
|
|
32033
|
-
code:
|
|
32453
|
+
code: z130.ZodIssueCode.custom,
|
|
32034
32454
|
path: [
|
|
32035
32455
|
"angle"
|
|
32036
32456
|
],
|
|
@@ -32039,7 +32459,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
32039
32459
|
}
|
|
32040
32460
|
if (input.kind === "landing" && !input.sectionKey && !input.instructions) {
|
|
32041
32461
|
ctx.addIssue({
|
|
32042
|
-
code:
|
|
32462
|
+
code: z130.ZodIssueCode.custom,
|
|
32043
32463
|
path: [
|
|
32044
32464
|
"instructions"
|
|
32045
32465
|
],
|
|
@@ -32085,7 +32505,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
32085
32505
|
for (const field of fieldsByKind[input.kind]) {
|
|
32086
32506
|
if (input[field] !== void 0) {
|
|
32087
32507
|
ctx.addIssue({
|
|
32088
|
-
code:
|
|
32508
|
+
code: z130.ZodIssueCode.custom,
|
|
32089
32509
|
path: [
|
|
32090
32510
|
field
|
|
32091
32511
|
],
|
|
@@ -32243,13 +32663,13 @@ function registerCreativeVariantTools(server, api) {
|
|
|
32243
32663
|
__name(registerCreativeVariantTools, "registerCreativeVariantTools");
|
|
32244
32664
|
|
|
32245
32665
|
// src/tools/script-review.ts
|
|
32246
|
-
import { z as
|
|
32666
|
+
import { z as z131 } from "zod";
|
|
32247
32667
|
var getVideoScriptGuidance = getProductMakerCapabilityModelGuidance("get_video_script");
|
|
32248
32668
|
var regenerateVideoScriptGuidance = getProductMakerCapabilityModelGuidance("regenerate_video_script");
|
|
32249
32669
|
var approveVideoScriptGuidance = getProductMakerCapabilityModelGuidance("approve_video_script");
|
|
32250
|
-
var GetVideoScriptInput =
|
|
32251
|
-
taskId:
|
|
32252
|
-
angleKey:
|
|
32670
|
+
var GetVideoScriptInput = z131.object({
|
|
32671
|
+
taskId: z131.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
|
|
32672
|
+
angleKey: z131.string().min(1).optional().describe('Clave persistida del \xE1ngulo cuyo guion se quiere leer (formato "angle_0", "angle_1", ...). Usa exactamente el angleKey recibido en reviewNextAction.calls al aprobar \xE1ngulos, incluso si s\xF3lo elegiste uno. Si se omite, el backend resuelve a "angle_0" literal; elegir el segundo candidato no crea angle_0. No derives esta clave del n\xFAmero visible del candidato.')
|
|
32253
32673
|
}).strict();
|
|
32254
32674
|
var ApproveVideoScriptInput = ApproveVideoScriptCapabilityRequest;
|
|
32255
32675
|
var RegenerateVideoScriptInput = RegenerateVideoScriptCapabilityRequest.extend({
|
|
@@ -32354,7 +32774,7 @@ Consulta get_task_status con esta tarea antes de reintentar. Si la tarea termin\
|
|
|
32354
32774
|
__name(registerScriptReviewTools, "registerScriptReviewTools");
|
|
32355
32775
|
|
|
32356
32776
|
// src/tools/connections.ts
|
|
32357
|
-
import { z as
|
|
32777
|
+
import { z as z132 } from "zod";
|
|
32358
32778
|
var listShopifyShopsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_shops");
|
|
32359
32779
|
var listShopifyProductsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_products");
|
|
32360
32780
|
var listMetaAdAccountsGuidance = getProductMakerCapabilityModelGuidance("list_meta_ad_accounts");
|
|
@@ -32363,7 +32783,7 @@ var listTikTokAdvertisersGuidance = getProductMakerCapabilityModelGuidance("list
|
|
|
32363
32783
|
function registerConnectionTools(server, api) {
|
|
32364
32784
|
server.registerTool("list_shopify_shops", {
|
|
32365
32785
|
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.",
|
|
32366
|
-
inputSchema:
|
|
32786
|
+
inputSchema: z132.object({}).shape,
|
|
32367
32787
|
annotations: READS_INTERNAL
|
|
32368
32788
|
}, async () => {
|
|
32369
32789
|
try {
|
|
@@ -32375,10 +32795,10 @@ function registerConnectionTools(server, api) {
|
|
|
32375
32795
|
});
|
|
32376
32796
|
server.registerTool("list_shopify_products", {
|
|
32377
32797
|
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.',
|
|
32378
|
-
inputSchema:
|
|
32379
|
-
shopDomain:
|
|
32380
|
-
query:
|
|
32381
|
-
taskId:
|
|
32798
|
+
inputSchema: z132.object({
|
|
32799
|
+
shopDomain: z132.string().min(3).max(120),
|
|
32800
|
+
query: z132.string().trim().max(120).optional(),
|
|
32801
|
+
taskId: z132.string().uuid().optional()
|
|
32382
32802
|
}).shape,
|
|
32383
32803
|
annotations: READS_EXTERNAL
|
|
32384
32804
|
}, async ({ shopDomain, query, taskId }) => {
|
|
@@ -32396,7 +32816,7 @@ function registerConnectionTools(server, api) {
|
|
|
32396
32816
|
});
|
|
32397
32817
|
server.registerTool("list_meta_ad_accounts", {
|
|
32398
32818
|
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.",
|
|
32399
|
-
inputSchema:
|
|
32819
|
+
inputSchema: z132.object({}).shape,
|
|
32400
32820
|
annotations: READS_EXTERNAL
|
|
32401
32821
|
}, async () => {
|
|
32402
32822
|
try {
|
|
@@ -32408,7 +32828,7 @@ function registerConnectionTools(server, api) {
|
|
|
32408
32828
|
});
|
|
32409
32829
|
server.registerTool("list_meta_destinations", {
|
|
32410
32830
|
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.",
|
|
32411
|
-
inputSchema:
|
|
32831
|
+
inputSchema: z132.object({}).shape,
|
|
32412
32832
|
annotations: READS_EXTERNAL,
|
|
32413
32833
|
_meta: {
|
|
32414
32834
|
"openai/widgetAccessible": true
|
|
@@ -32423,7 +32843,7 @@ function registerConnectionTools(server, api) {
|
|
|
32423
32843
|
});
|
|
32424
32844
|
server.registerTool("list_tiktok_advertisers", {
|
|
32425
32845
|
description: listTikTokAdvertisersGuidance.summary + " Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar TikTok en productmaker.app/integrations.",
|
|
32426
|
-
inputSchema:
|
|
32846
|
+
inputSchema: z132.object({}).shape,
|
|
32427
32847
|
annotations: READS_EXTERNAL
|
|
32428
32848
|
}, async () => {
|
|
32429
32849
|
try {
|
|
@@ -32437,7 +32857,7 @@ function registerConnectionTools(server, api) {
|
|
|
32437
32857
|
__name(registerConnectionTools, "registerConnectionTools");
|
|
32438
32858
|
|
|
32439
32859
|
// src/tools/actors.ts
|
|
32440
|
-
import { z as
|
|
32860
|
+
import { z as z133 } from "zod";
|
|
32441
32861
|
var listActorsGuidance = getProductMakerCapabilityModelGuidance("list_actors");
|
|
32442
32862
|
var actorVoiceGuidance = {
|
|
32443
32863
|
capabilities: getProductMakerCapabilityModelGuidance("get_actor_voice_capabilities"),
|
|
@@ -32477,7 +32897,7 @@ function sanitizeVoiceResult(value) {
|
|
|
32477
32897
|
__name(sanitizeVoiceResult, "sanitizeVoiceResult");
|
|
32478
32898
|
function registerActorTools(server, api) {
|
|
32479
32899
|
const actor = {
|
|
32480
|
-
actorId:
|
|
32900
|
+
actorId: z133.string().min(1).max(64)
|
|
32481
32901
|
};
|
|
32482
32902
|
const safe = /* @__PURE__ */ __name(async (request) => {
|
|
32483
32903
|
try {
|
|
@@ -32506,8 +32926,8 @@ function registerActorTools(server, api) {
|
|
|
32506
32926
|
inputSchema: {
|
|
32507
32927
|
...actor,
|
|
32508
32928
|
draft: ActorVoiceDraftSchema,
|
|
32509
|
-
requestKey:
|
|
32510
|
-
acceptedQuoteId:
|
|
32929
|
+
requestKey: z133.string().trim().min(1).max(128),
|
|
32930
|
+
acceptedQuoteId: z133.string().trim().min(1).max(128)
|
|
32511
32931
|
},
|
|
32512
32932
|
annotations: CREATES_PAID
|
|
32513
32933
|
}, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/previews`, body)));
|
|
@@ -32515,7 +32935,7 @@ function registerActorTools(server, api) {
|
|
|
32515
32935
|
description: actorVoiceGuidance.get.summary,
|
|
32516
32936
|
inputSchema: {
|
|
32517
32937
|
...actor,
|
|
32518
|
-
candidateId:
|
|
32938
|
+
candidateId: z133.string().min(1).max(64)
|
|
32519
32939
|
},
|
|
32520
32940
|
// Polling can resume the first paid submission of an accepted quote.
|
|
32521
32941
|
// The immutable candidate/operation key keeps recovery idempotent.
|
|
@@ -32528,16 +32948,16 @@ function registerActorTools(server, api) {
|
|
|
32528
32948
|
description: actorVoiceGuidance.approve.summary,
|
|
32529
32949
|
inputSchema: {
|
|
32530
32950
|
...actor,
|
|
32531
|
-
candidateId:
|
|
32532
|
-
expectedRevision:
|
|
32533
|
-
expectedApprovedRevision:
|
|
32951
|
+
candidateId: z133.string().min(1).max(64),
|
|
32952
|
+
expectedRevision: z133.number().int().positive(),
|
|
32953
|
+
expectedApprovedRevision: z133.number().int().positive().nullable().optional()
|
|
32534
32954
|
},
|
|
32535
32955
|
// Replaces the selected voice and withdraws the old catalog grants.
|
|
32536
32956
|
annotations: OVERWRITES_INTERNAL
|
|
32537
32957
|
}, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/approve`, body)));
|
|
32538
32958
|
server.registerTool("list_actors", {
|
|
32539
32959
|
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.",
|
|
32540
|
-
inputSchema:
|
|
32960
|
+
inputSchema: z133.object({}).shape,
|
|
32541
32961
|
annotations: READS_INTERNAL
|
|
32542
32962
|
}, async () => {
|
|
32543
32963
|
try {
|
|
@@ -32570,7 +32990,7 @@ function registerActorTools(server, api) {
|
|
|
32570
32990
|
__name(registerActorTools, "registerActorTools");
|
|
32571
32991
|
|
|
32572
32992
|
// src/tools/publish.ts
|
|
32573
|
-
import { z as
|
|
32993
|
+
import { z as z134 } from "zod";
|
|
32574
32994
|
|
|
32575
32995
|
// src/tools/meta-publish-attempt-id.ts
|
|
32576
32996
|
var META_PUBLISH_NAMESPACE = "7b19c9ac-b4eb-4db1-970e-c2f24ce30b98";
|
|
@@ -32609,40 +33029,40 @@ var publishToShopifyGuidance = getProductMakerCapabilityModelGuidance("publish_t
|
|
|
32609
33029
|
var publishToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_to_meta");
|
|
32610
33030
|
var publishCreativesToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_creatives_to_meta");
|
|
32611
33031
|
var publishToTikTokGuidance = getProductMakerCapabilityModelGuidance("publish_to_tiktok");
|
|
32612
|
-
var ShopifyInput =
|
|
32613
|
-
taskId:
|
|
32614
|
-
shopDomain:
|
|
33032
|
+
var ShopifyInput = z134.object({
|
|
33033
|
+
taskId: z134.string().min(1),
|
|
33034
|
+
shopDomain: z134.string().min(1),
|
|
32615
33035
|
/** Override: number of landing images to include. Default = ALL images the
|
|
32616
33036
|
* task generated (the MCP fetches /v1/results first to count). Bounded
|
|
32617
33037
|
* generously here; the backend validates each index against
|
|
32618
33038
|
* landing.images.length and rejects out-of-range. */
|
|
32619
|
-
numLandingImages:
|
|
32620
|
-
variantIndex:
|
|
33039
|
+
numLandingImages: z134.number().int().min(1).max(20).optional(),
|
|
33040
|
+
variantIndex: z134.number().int().min(0).optional(),
|
|
32621
33041
|
/** ASK THE USER before setting: "¿Tu producto tiene variantes (talla, color, etc.)?".
|
|
32622
33042
|
* When true, the landing renders variant-picker pills; when false, it ships
|
|
32623
33043
|
* a single-option product page. Defaults to false. */
|
|
32624
|
-
showVariantPicker:
|
|
33044
|
+
showVariantPicker: z134.boolean().optional(),
|
|
32625
33045
|
/** Default `auto` updates the product previously published for this task and
|
|
32626
33046
|
* shop. Use `existing` with targetProductId to choose another product, or
|
|
32627
33047
|
* `new` only when the user explicitly wants a duplicate/new listing. */
|
|
32628
|
-
publicationMode:
|
|
33048
|
+
publicationMode: z134.enum([
|
|
32629
33049
|
"auto",
|
|
32630
33050
|
"existing",
|
|
32631
33051
|
"new"
|
|
32632
33052
|
]).optional(),
|
|
32633
33053
|
/** Shopify product GID, numeric id, or admin product URL. Required when
|
|
32634
33054
|
* publicationMode is `existing`. */
|
|
32635
|
-
targetProductId:
|
|
33055
|
+
targetProductId: z134.string().trim().min(1).max(300).optional(),
|
|
32636
33056
|
/** Add an announcement bar text above add-to-cart (optional). */
|
|
32637
|
-
announcementBarEnabled:
|
|
32638
|
-
announcementBarText:
|
|
33057
|
+
announcementBarEnabled: z134.boolean().optional(),
|
|
33058
|
+
announcementBarText: z134.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
|
|
32639
33059
|
commerceCorrection: PublishCommerceCorrectionSchema.optional().describe("Complete seller-confirmed commerce values, with the revision and fingerprint returned in recovery. Never invent missing prices or convert currency."),
|
|
32640
|
-
confirmed:
|
|
33060
|
+
confirmed: z134.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
|
|
32641
33061
|
});
|
|
32642
33062
|
var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value, ctx) => {
|
|
32643
33063
|
if (value.commerceCorrection && value.confirmed !== true) {
|
|
32644
33064
|
ctx.addIssue({
|
|
32645
|
-
code:
|
|
33065
|
+
code: z134.ZodIssueCode.custom,
|
|
32646
33066
|
path: [
|
|
32647
33067
|
"confirmed"
|
|
32648
33068
|
],
|
|
@@ -32651,7 +33071,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
32651
33071
|
}
|
|
32652
33072
|
if (value.announcementBarEnabled && !value.announcementBarText) {
|
|
32653
33073
|
ctx.addIssue({
|
|
32654
|
-
code:
|
|
33074
|
+
code: z134.ZodIssueCode.custom,
|
|
32655
33075
|
path: [
|
|
32656
33076
|
"announcementBarText"
|
|
32657
33077
|
],
|
|
@@ -32660,7 +33080,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
32660
33080
|
}
|
|
32661
33081
|
if (!value.announcementBarEnabled && value.announcementBarText) {
|
|
32662
33082
|
ctx.addIssue({
|
|
32663
|
-
code:
|
|
33083
|
+
code: z134.ZodIssueCode.custom,
|
|
32664
33084
|
path: [
|
|
32665
33085
|
"announcementBarText"
|
|
32666
33086
|
],
|
|
@@ -32674,90 +33094,90 @@ function parseShopifyInput(rawInput) {
|
|
|
32674
33094
|
return parsed.data;
|
|
32675
33095
|
}
|
|
32676
33096
|
__name(parseShopifyInput, "parseShopifyInput");
|
|
32677
|
-
var McpCampaignConfig =
|
|
33097
|
+
var McpCampaignConfig = z134.object({
|
|
32678
33098
|
/** Legacy USD amount. Meta retains its existing conversion; the TikTok
|
|
32679
33099
|
* schema below restricts this input to USD advertiser accounts. */
|
|
32680
|
-
dailyBudgetUsd:
|
|
33100
|
+
dailyBudgetUsd: z134.number().positive().optional(),
|
|
32681
33101
|
/** ISO-3166-1 alpha-2 country codes or resolvable names (CountryIso2Schema
|
|
32682
33102
|
* normalizes at validation). Meta accepts max 1 (single-country ad set).
|
|
32683
33103
|
* TikTok takes only the first entry. */
|
|
32684
|
-
targetCountries:
|
|
32685
|
-
campaignName:
|
|
33104
|
+
targetCountries: z134.array(CountryIso2Schema).max(1).optional(),
|
|
33105
|
+
campaignName: z134.string().trim().min(1).max(100).optional()
|
|
32686
33106
|
});
|
|
32687
33107
|
var McpAdAccountId = MetaAdAccountId.describe('Meta ad account id. Accepts "act_1234567890" or the bare numeric id "1234567890".');
|
|
32688
|
-
var MetaInput =
|
|
32689
|
-
taskId:
|
|
33108
|
+
var MetaInput = z134.object({
|
|
33109
|
+
taskId: z134.string().min(1),
|
|
32690
33110
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
32691
|
-
portfolioId:
|
|
33111
|
+
portfolioId: z134.string().trim().min(1),
|
|
32692
33112
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
32693
|
-
pageId:
|
|
33113
|
+
pageId: z134.string().trim().min(1),
|
|
32694
33114
|
adAccountId: McpAdAccountId,
|
|
32695
|
-
pixelId:
|
|
32696
|
-
landingUrl:
|
|
33115
|
+
pixelId: z134.string().min(1).optional(),
|
|
33116
|
+
landingUrl: z134.string().url().optional(),
|
|
32697
33117
|
/** Select which angles to publish by 0-based index. Omit to publish all
|
|
32698
33118
|
* successful angles. Example: a task with 3 angles → `[0,2]` publishes #0 + #2. */
|
|
32699
|
-
angleIndexes:
|
|
33119
|
+
angleIndexes: z134.array(z134.number().int().nonnegative()).optional(),
|
|
32700
33120
|
campaignConfig: McpCampaignConfig.optional(),
|
|
32701
33121
|
/** Override the ad's primary text (body copy). If omitted, ProductMaker
|
|
32702
33122
|
* uses the auto-generated copy attached to the task. Capped at 500 chars
|
|
32703
33123
|
* (Meta's primary-text limit). */
|
|
32704
|
-
primaryText:
|
|
33124
|
+
primaryText: z134.string().trim().min(1).max(500).optional(),
|
|
32705
33125
|
/** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
|
|
32706
33126
|
* (wa.me) instead of a landing page. */
|
|
32707
|
-
phoneNumber:
|
|
33127
|
+
phoneNumber: z134.string().min(8).max(32).optional()
|
|
32708
33128
|
});
|
|
32709
|
-
var GroupedTaskSource =
|
|
32710
|
-
type:
|
|
32711
|
-
taskId:
|
|
32712
|
-
angleIndex:
|
|
32713
|
-
videoVariant:
|
|
33129
|
+
var GroupedTaskSource = z134.object({
|
|
33130
|
+
type: z134.literal("task"),
|
|
33131
|
+
taskId: z134.string().min(1),
|
|
33132
|
+
angleIndex: z134.number().int().min(0).optional(),
|
|
33133
|
+
videoVariant: z134.enum([
|
|
32714
33134
|
"with_subtitles",
|
|
32715
33135
|
"without_subtitles"
|
|
32716
33136
|
]).optional(),
|
|
32717
|
-
imageVariantIndex:
|
|
32718
|
-
});
|
|
32719
|
-
var GroupedMediaSource =
|
|
32720
|
-
type:
|
|
32721
|
-
url:
|
|
32722
|
-
path:
|
|
32723
|
-
thumbnailUrl:
|
|
32724
|
-
thumbnailPath:
|
|
33137
|
+
imageVariantIndex: z134.number().int().min(0).optional()
|
|
33138
|
+
});
|
|
33139
|
+
var GroupedMediaSource = z134.object({
|
|
33140
|
+
type: z134.literal("media"),
|
|
33141
|
+
url: z134.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
|
|
33142
|
+
path: z134.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".'),
|
|
33143
|
+
thumbnailUrl: z134.string().url().optional(),
|
|
33144
|
+
thumbnailPath: z134.string().min(1).optional()
|
|
32725
33145
|
}).refine((value) => Boolean(value.url) !== Boolean(value.path), {
|
|
32726
33146
|
message: "media source needs exactly one of `url` or `path`"
|
|
32727
33147
|
}).refine((value) => !(value.thumbnailUrl && value.thumbnailPath), {
|
|
32728
33148
|
message: "media source needs at most one of `thumbnailUrl` or `thumbnailPath`"
|
|
32729
33149
|
});
|
|
32730
|
-
var GroupedUploadedAssetSource =
|
|
32731
|
-
type:
|
|
33150
|
+
var GroupedUploadedAssetSource = z134.object({
|
|
33151
|
+
type: z134.literal("asset"),
|
|
32732
33152
|
/** Returned by check_media_upload. ProductMaker resolves ownership server-side. */
|
|
32733
|
-
assetId:
|
|
32734
|
-
thumbnailAssetId:
|
|
33153
|
+
assetId: z134.string().uuid(),
|
|
33154
|
+
thumbnailAssetId: z134.string().uuid().optional()
|
|
32735
33155
|
});
|
|
32736
|
-
var GroupedCreative =
|
|
32737
|
-
type:
|
|
33156
|
+
var GroupedCreative = z134.object({
|
|
33157
|
+
type: z134.enum([
|
|
32738
33158
|
"image",
|
|
32739
33159
|
"video"
|
|
32740
33160
|
]),
|
|
32741
|
-
source:
|
|
33161
|
+
source: z134.union([
|
|
32742
33162
|
GroupedTaskSource,
|
|
32743
33163
|
GroupedMediaSource,
|
|
32744
33164
|
GroupedUploadedAssetSource
|
|
32745
33165
|
]),
|
|
32746
|
-
title:
|
|
32747
|
-
description:
|
|
33166
|
+
title: z134.string().max(120).optional(),
|
|
33167
|
+
description: z134.string().max(500).optional(),
|
|
32748
33168
|
cta: MetaCtaType.optional(),
|
|
32749
|
-
creativeId:
|
|
33169
|
+
creativeId: z134.string().min(1).optional()
|
|
32750
33170
|
});
|
|
32751
|
-
var GroupedCampaignConfigBase =
|
|
33171
|
+
var GroupedCampaignConfigBase = z134.object({
|
|
32752
33172
|
campaignType: MetaCampaignType.default("sales"),
|
|
32753
33173
|
optimizationMode: MetaOptimizationMode.default("advantage_plus"),
|
|
32754
33174
|
budgetMode: MetaBudgetMode.optional(),
|
|
32755
|
-
campaignDailyBudget:
|
|
32756
|
-
adSets:
|
|
32757
|
-
tempId:
|
|
32758
|
-
name:
|
|
32759
|
-
dailyBudget:
|
|
32760
|
-
creativeIds:
|
|
33175
|
+
campaignDailyBudget: z134.number().int().positive().optional(),
|
|
33176
|
+
adSets: z134.array(z134.object({
|
|
33177
|
+
tempId: z134.string().min(1).max(80),
|
|
33178
|
+
name: z134.string().min(1).max(100),
|
|
33179
|
+
dailyBudget: z134.number().int().positive().optional(),
|
|
33180
|
+
creativeIds: z134.array(z134.string().min(1)).min(1)
|
|
32761
33181
|
})).min(1).max(CAMPAIGN_LIMITS.MAX_AD_SETS),
|
|
32762
33182
|
/**
|
|
32763
33183
|
* Valid values are 'landing' and 'whatsapp' — there is no 'website'. This
|
|
@@ -32765,17 +33185,17 @@ var GroupedCampaignConfigBase = z133.object({
|
|
|
32765
33185
|
* opaque `invalid_literal` and made the WhatsApp destination — supported by
|
|
32766
33186
|
* the API since #849 — unreachable from this tool.
|
|
32767
33187
|
*/
|
|
32768
|
-
destination:
|
|
32769
|
-
|
|
32770
|
-
type:
|
|
32771
|
-
landingUrl:
|
|
33188
|
+
destination: z134.discriminatedUnion("type", [
|
|
33189
|
+
z134.object({
|
|
33190
|
+
type: z134.literal("landing"),
|
|
33191
|
+
landingUrl: z134.string().url()
|
|
32772
33192
|
}),
|
|
32773
|
-
|
|
32774
|
-
type:
|
|
32775
|
-
phoneNumber:
|
|
33193
|
+
z134.object({
|
|
33194
|
+
type: z134.literal("whatsapp"),
|
|
33195
|
+
phoneNumber: z134.string().min(8).max(32)
|
|
32776
33196
|
})
|
|
32777
33197
|
]),
|
|
32778
|
-
saveAsDefault:
|
|
33198
|
+
saveAsDefault: z134.boolean().default(false),
|
|
32779
33199
|
budgetPolicy: MetaBudgetPolicy.optional()
|
|
32780
33200
|
});
|
|
32781
33201
|
function resolveBudgetMode(value) {
|
|
@@ -32789,7 +33209,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
32789
33209
|
const budgetMode = resolveBudgetMode(value);
|
|
32790
33210
|
if (budgetMode === "campaign" && value.campaignDailyBudget === void 0) {
|
|
32791
33211
|
ctx.addIssue({
|
|
32792
|
-
code:
|
|
33212
|
+
code: z134.ZodIssueCode.custom,
|
|
32793
33213
|
path: [
|
|
32794
33214
|
"campaignDailyBudget"
|
|
32795
33215
|
],
|
|
@@ -32800,7 +33220,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
32800
33220
|
value.adSets.forEach((adSet, index) => {
|
|
32801
33221
|
if (adSet.dailyBudget === void 0) {
|
|
32802
33222
|
ctx.addIssue({
|
|
32803
|
-
code:
|
|
33223
|
+
code: z134.ZodIssueCode.custom,
|
|
32804
33224
|
path: [
|
|
32805
33225
|
"adSets",
|
|
32806
33226
|
index,
|
|
@@ -32815,25 +33235,25 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
32815
33235
|
...value,
|
|
32816
33236
|
budgetMode: resolveBudgetMode(value)
|
|
32817
33237
|
}));
|
|
32818
|
-
var PublishCreativesToMetaInputBase =
|
|
32819
|
-
creatives:
|
|
33238
|
+
var PublishCreativesToMetaInputBase = z134.object({
|
|
33239
|
+
creatives: z134.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
|
|
32820
33240
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
32821
|
-
portfolioId:
|
|
33241
|
+
portfolioId: z134.string().trim().min(1),
|
|
32822
33242
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
32823
|
-
pageId:
|
|
33243
|
+
pageId: z134.string().trim().min(1),
|
|
32824
33244
|
adAccountId: McpAdAccountId,
|
|
32825
|
-
pixelId:
|
|
33245
|
+
pixelId: z134.string().min(1).optional(),
|
|
32826
33246
|
/** Required unless `campaignConfig.destination` is whatsapp or a creative
|
|
32827
33247
|
* comes from a task (the API then lands on the published service landing
|
|
32828
33248
|
* of its service tasks) — see the superRefine below. Mirrors the API's
|
|
32829
33249
|
* `FacebookCreateCampaignFromTasksBodySchema`. */
|
|
32830
|
-
landingUrl:
|
|
33250
|
+
landingUrl: z134.string().url().optional(),
|
|
32831
33251
|
/** ISO-2 code or resolvable country name — mirrors the API contract
|
|
32832
33252
|
* (CountryIso2Schema), which normalizes names to alpha-2 at validation.
|
|
32833
33253
|
* Omitted: the brand country of its service tasks (the API answers
|
|
32834
33254
|
* META_NO_TARGET_COUNTRY when it has none); "US" for products. */
|
|
32835
33255
|
targetCountry: CountryIso2Schema.optional(),
|
|
32836
|
-
campaignName:
|
|
33256
|
+
campaignName: z134.string().trim().min(1).max(100),
|
|
32837
33257
|
campaignConfig: GroupedCampaignConfig.optional()
|
|
32838
33258
|
});
|
|
32839
33259
|
var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((value, ctx) => {
|
|
@@ -32841,7 +33261,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
32841
33261
|
const hasTaskCreative = value.creatives.some((creative) => creative.source.type === "task");
|
|
32842
33262
|
if (destination?.type !== "whatsapp" && destination?.type !== "landing" && !value.landingUrl && !hasTaskCreative) {
|
|
32843
33263
|
ctx.addIssue({
|
|
32844
|
-
code:
|
|
33264
|
+
code: z134.ZodIssueCode.custom,
|
|
32845
33265
|
path: [
|
|
32846
33266
|
"landingUrl"
|
|
32847
33267
|
],
|
|
@@ -32850,7 +33270,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
32850
33270
|
}
|
|
32851
33271
|
if (destination?.type === "landing" && value.landingUrl && destination.landingUrl !== value.landingUrl) {
|
|
32852
33272
|
ctx.addIssue({
|
|
32853
|
-
code:
|
|
33273
|
+
code: z134.ZodIssueCode.custom,
|
|
32854
33274
|
path: [
|
|
32855
33275
|
"campaignConfig",
|
|
32856
33276
|
"destination",
|
|
@@ -32869,16 +33289,16 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
32869
33289
|
}
|
|
32870
33290
|
return value;
|
|
32871
33291
|
});
|
|
32872
|
-
var PresignUploadResponseSchema =
|
|
32873
|
-
uploadUrl:
|
|
33292
|
+
var PresignUploadResponseSchema = z134.object({
|
|
33293
|
+
uploadUrl: z134.string().url().refine((value) => {
|
|
32874
33294
|
const url = new URL(value);
|
|
32875
33295
|
return !url.username && !url.password && url.protocol === "https:";
|
|
32876
33296
|
}, "presigned upload URL must be HTTPS without embedded credentials"),
|
|
32877
|
-
publicUrl:
|
|
33297
|
+
publicUrl: z134.string().url().refine((value) => {
|
|
32878
33298
|
const url = new URL(value);
|
|
32879
33299
|
return !url.username && !url.password;
|
|
32880
33300
|
}, "public media URL must not contain embedded credentials"),
|
|
32881
|
-
stagingAssetId:
|
|
33301
|
+
stagingAssetId: z134.string().uuid()
|
|
32882
33302
|
});
|
|
32883
33303
|
async function uploadResolvedMedia(api, media, assetRole) {
|
|
32884
33304
|
if (!media.buffer) throw new ResolveMediaError("INVALID_INPUT", "resolved media has no bytes");
|
|
@@ -32904,14 +33324,14 @@ async function resolveAndUploadMedia(api, ref, expectedKind, assetRole, transpor
|
|
|
32904
33324
|
}
|
|
32905
33325
|
__name(resolveAndUploadMedia, "resolveAndUploadMedia");
|
|
32906
33326
|
var TikTokMcpCampaignConfig = McpCampaignConfig.extend({
|
|
32907
|
-
dailyBudgetUsd:
|
|
32908
|
-
dailyBudget:
|
|
33327
|
+
dailyBudgetUsd: z134.number().finite().positive().optional().describe("Legacy USD amount, supported only for USD advertiser accounts. No FX conversion."),
|
|
33328
|
+
dailyBudget: z134.number().finite().positive().optional().describe("Daily budget in the selected advertiser currency major units; pass budgetCurrency together."),
|
|
32909
33329
|
budgetCurrency: TikTokBudgetCurrencySchema.optional(),
|
|
32910
33330
|
destination: TikTokCampaignDestinationSchema.optional()
|
|
32911
33331
|
}).superRefine((value, ctx) => {
|
|
32912
33332
|
if (value.dailyBudgetUsd !== void 0 && (value.dailyBudget !== void 0 || value.budgetCurrency !== void 0)) {
|
|
32913
33333
|
ctx.addIssue({
|
|
32914
|
-
code:
|
|
33334
|
+
code: z134.ZodIssueCode.custom,
|
|
32915
33335
|
path: [
|
|
32916
33336
|
"dailyBudgetUsd"
|
|
32917
33337
|
],
|
|
@@ -32920,7 +33340,7 @@ var TikTokMcpCampaignConfig = McpCampaignConfig.extend({
|
|
|
32920
33340
|
}
|
|
32921
33341
|
if (value.dailyBudget !== void 0 !== (value.budgetCurrency !== void 0)) {
|
|
32922
33342
|
ctx.addIssue({
|
|
32923
|
-
code:
|
|
33343
|
+
code: z134.ZodIssueCode.custom,
|
|
32924
33344
|
path: [
|
|
32925
33345
|
"budgetCurrency"
|
|
32926
33346
|
],
|
|
@@ -32928,16 +33348,16 @@ var TikTokMcpCampaignConfig = McpCampaignConfig.extend({
|
|
|
32928
33348
|
});
|
|
32929
33349
|
}
|
|
32930
33350
|
});
|
|
32931
|
-
var TikTokInput =
|
|
32932
|
-
taskId:
|
|
32933
|
-
advertiserId:
|
|
32934
|
-
pixelId:
|
|
32935
|
-
landingUrl:
|
|
32936
|
-
angleIndexes:
|
|
33351
|
+
var TikTokInput = z134.object({
|
|
33352
|
+
taskId: z134.string().min(1),
|
|
33353
|
+
advertiserId: z134.string().min(1),
|
|
33354
|
+
pixelId: z134.string().min(1).optional(),
|
|
33355
|
+
landingUrl: z134.string().url().optional(),
|
|
33356
|
+
angleIndexes: z134.array(z134.number().int().nonnegative()).optional(),
|
|
32937
33357
|
campaignConfig: TikTokMcpCampaignConfig.optional(),
|
|
32938
33358
|
/** Override the ad's description (TikTok's body copy). If omitted,
|
|
32939
33359
|
* ProductMaker uses the auto-generated copy attached to the task. */
|
|
32940
|
-
primaryText:
|
|
33360
|
+
primaryText: z134.string().trim().min(1).max(500).optional()
|
|
32941
33361
|
});
|
|
32942
33362
|
function registerPublishTools(server, api, opts = {}) {
|
|
32943
33363
|
const transport = opts.transport ?? "http";
|
|
@@ -33296,39 +33716,39 @@ __name(toTikTokCampaignConfig, "toTikTokCampaignConfig");
|
|
|
33296
33716
|
|
|
33297
33717
|
// src/tools/meta-upload.ts
|
|
33298
33718
|
import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
|
|
33299
|
-
import { z as
|
|
33719
|
+
import { z as z135 } from "zod";
|
|
33300
33720
|
var requestMediaUploadGuidance = getProductMakerCapabilityModelGuidance("request_media_upload");
|
|
33301
|
-
var UploadSessionInputBase =
|
|
33302
|
-
mediaKind:
|
|
33721
|
+
var UploadSessionInputBase = z135.object({
|
|
33722
|
+
mediaKind: z135.enum([
|
|
33303
33723
|
"image",
|
|
33304
33724
|
"video",
|
|
33305
33725
|
"mixed"
|
|
33306
33726
|
]).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."),
|
|
33307
|
-
assetRole:
|
|
33727
|
+
assetRole: z135.enum([
|
|
33308
33728
|
"media",
|
|
33309
33729
|
"thumbnail"
|
|
33310
33730
|
]).default("media").describe("Use media for the creative itself; thumbnail only for an image thumbnail."),
|
|
33311
|
-
uploadPurpose:
|
|
33731
|
+
uploadPurpose: z135.enum([
|
|
33312
33732
|
"product_reference",
|
|
33313
33733
|
"creative",
|
|
33314
33734
|
"generic"
|
|
33315
33735
|
]).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."),
|
|
33316
|
-
maxFiles:
|
|
33736
|
+
maxFiles: z135.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
|
|
33317
33737
|
});
|
|
33318
|
-
var OpenAiFileReference =
|
|
33319
|
-
download_url:
|
|
33320
|
-
file_id:
|
|
33321
|
-
mime_type:
|
|
33322
|
-
file_name:
|
|
33738
|
+
var OpenAiFileReference = z135.object({
|
|
33739
|
+
download_url: z135.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."),
|
|
33740
|
+
file_id: z135.string().min(1),
|
|
33741
|
+
mime_type: z135.string().min(1).optional(),
|
|
33742
|
+
file_name: z135.string().min(1).optional()
|
|
33323
33743
|
});
|
|
33324
33744
|
var UploadSessionToolInputShape = {
|
|
33325
33745
|
...UploadSessionInputBase.shape,
|
|
33326
|
-
files:
|
|
33746
|
+
files: z135.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.")
|
|
33327
33747
|
};
|
|
33328
|
-
var UploadSessionToolInput =
|
|
33748
|
+
var UploadSessionToolInput = z135.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
|
|
33329
33749
|
if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
|
|
33330
33750
|
ctx.addIssue({
|
|
33331
|
-
code:
|
|
33751
|
+
code: z135.ZodIssueCode.custom,
|
|
33332
33752
|
path: [
|
|
33333
33753
|
"mediaKind"
|
|
33334
33754
|
],
|
|
@@ -33337,7 +33757,7 @@ var UploadSessionToolInput = z134.object(UploadSessionToolInputShape).superRefin
|
|
|
33337
33757
|
}
|
|
33338
33758
|
if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
|
|
33339
33759
|
ctx.addIssue({
|
|
33340
|
-
code:
|
|
33760
|
+
code: z135.ZodIssueCode.custom,
|
|
33341
33761
|
path: [
|
|
33342
33762
|
"maxFiles"
|
|
33343
33763
|
],
|
|
@@ -33346,7 +33766,7 @@ var UploadSessionToolInput = z134.object(UploadSessionToolInputShape).superRefin
|
|
|
33346
33766
|
}
|
|
33347
33767
|
if (value.mediaKind === "image" && (value.maxFiles ?? 1) > 5) {
|
|
33348
33768
|
ctx.addIssue({
|
|
33349
|
-
code:
|
|
33769
|
+
code: z135.ZodIssueCode.custom,
|
|
33350
33770
|
path: [
|
|
33351
33771
|
"maxFiles"
|
|
33352
33772
|
],
|
|
@@ -33354,38 +33774,38 @@ var UploadSessionToolInput = z134.object(UploadSessionToolInputShape).superRefin
|
|
|
33354
33774
|
});
|
|
33355
33775
|
}
|
|
33356
33776
|
});
|
|
33357
|
-
var UploadSessionResponse =
|
|
33358
|
-
sessionId:
|
|
33359
|
-
uploadPageUrl:
|
|
33360
|
-
mediaKind:
|
|
33777
|
+
var UploadSessionResponse = z135.object({
|
|
33778
|
+
sessionId: z135.string().uuid(),
|
|
33779
|
+
uploadPageUrl: z135.string().url(),
|
|
33780
|
+
mediaKind: z135.enum([
|
|
33361
33781
|
"image",
|
|
33362
33782
|
"video",
|
|
33363
33783
|
"mixed"
|
|
33364
33784
|
]),
|
|
33365
|
-
assetRole:
|
|
33785
|
+
assetRole: z135.enum([
|
|
33366
33786
|
"media",
|
|
33367
33787
|
"thumbnail"
|
|
33368
33788
|
]),
|
|
33369
|
-
maxFiles:
|
|
33370
|
-
expiresAt:
|
|
33789
|
+
maxFiles: z135.number().int().positive(),
|
|
33790
|
+
expiresAt: z135.string().datetime()
|
|
33371
33791
|
});
|
|
33372
|
-
var UploadStatusInput =
|
|
33373
|
-
sessionId:
|
|
33792
|
+
var UploadStatusInput = z135.object({
|
|
33793
|
+
sessionId: z135.string().uuid().describe("The sessionId returned by request_media_upload.")
|
|
33374
33794
|
});
|
|
33375
|
-
var UniversalUploadStatusResponse =
|
|
33376
|
-
|
|
33377
|
-
status:
|
|
33378
|
-
assets:
|
|
33795
|
+
var UniversalUploadStatusResponse = z135.discriminatedUnion("status", [
|
|
33796
|
+
z135.object({
|
|
33797
|
+
status: z135.literal("pending"),
|
|
33798
|
+
assets: z135.array(z135.never()).length(0)
|
|
33379
33799
|
}),
|
|
33380
|
-
|
|
33381
|
-
status:
|
|
33382
|
-
assets:
|
|
33383
|
-
assetId:
|
|
33384
|
-
mediaKind:
|
|
33800
|
+
z135.object({
|
|
33801
|
+
status: z135.literal("uploaded"),
|
|
33802
|
+
assets: z135.array(z135.object({
|
|
33803
|
+
assetId: z135.string().uuid(),
|
|
33804
|
+
mediaKind: z135.enum([
|
|
33385
33805
|
"image",
|
|
33386
33806
|
"video"
|
|
33387
33807
|
]),
|
|
33388
|
-
assetRole:
|
|
33808
|
+
assetRole: z135.enum([
|
|
33389
33809
|
"media",
|
|
33390
33810
|
"thumbnail"
|
|
33391
33811
|
])
|
|
@@ -33393,13 +33813,13 @@ var UniversalUploadStatusResponse = z134.discriminatedUnion("status", [
|
|
|
33393
33813
|
})
|
|
33394
33814
|
]);
|
|
33395
33815
|
var UniversalUploadStructuredResponse = UploadSessionResponse.extend({
|
|
33396
|
-
uploadPurpose:
|
|
33816
|
+
uploadPurpose: z135.enum([
|
|
33397
33817
|
"product_reference",
|
|
33398
33818
|
"creative",
|
|
33399
33819
|
"generic"
|
|
33400
33820
|
]),
|
|
33401
|
-
checkToolName:
|
|
33402
|
-
resolveEndpoint:
|
|
33821
|
+
checkToolName: z135.literal("check_media_upload"),
|
|
33822
|
+
resolveEndpoint: z135.string().url()
|
|
33403
33823
|
});
|
|
33404
33824
|
function contextualizeUploadPageUrl(uploadPageUrl, uploadPurpose) {
|
|
33405
33825
|
const url = new URL(uploadPageUrl);
|
|
@@ -33490,15 +33910,15 @@ function registerMediaUploadTools(server, api) {
|
|
|
33490
33910
|
__name(registerMediaUploadTools, "registerMediaUploadTools");
|
|
33491
33911
|
|
|
33492
33912
|
// src/tools/campaigns.ts
|
|
33493
|
-
import { z as
|
|
33913
|
+
import { z as z136 } from "zod";
|
|
33494
33914
|
var getMetaCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_meta_campaign_status");
|
|
33495
33915
|
var getTikTokCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_tiktok_campaign_status");
|
|
33496
|
-
var MetaStatusInput =
|
|
33497
|
-
campaignId:
|
|
33916
|
+
var MetaStatusInput = z136.object({
|
|
33917
|
+
campaignId: z136.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
|
|
33498
33918
|
});
|
|
33499
|
-
var TikTokStatusInput =
|
|
33500
|
-
campaignId:
|
|
33501
|
-
advertiserId:
|
|
33919
|
+
var TikTokStatusInput = z136.object({
|
|
33920
|
+
campaignId: z136.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
|
|
33921
|
+
advertiserId: z136.string().min(1).describe("The same advertiserId used to publish the campaign.")
|
|
33502
33922
|
});
|
|
33503
33923
|
function registerCampaignTools(server, api) {
|
|
33504
33924
|
server.registerTool("get_meta_campaign_status", {
|
|
@@ -33603,10 +34023,10 @@ function renderTikTokStatusMarkdown(r) {
|
|
|
33603
34023
|
__name(renderTikTokStatusMarkdown, "renderTikTokStatusMarkdown");
|
|
33604
34024
|
|
|
33605
34025
|
// ../../packages/product-economics/src/product-costing.ts
|
|
33606
|
-
import { z as
|
|
34026
|
+
import { z as z138 } from "zod";
|
|
33607
34027
|
|
|
33608
34028
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
33609
|
-
import { z as
|
|
34029
|
+
import { z as z137 } from "zod";
|
|
33610
34030
|
|
|
33611
34031
|
// ../../packages/product-economics/src/product-costing-shipping-references.json
|
|
33612
34032
|
var product_costing_shipping_references_default = {
|
|
@@ -33670,21 +34090,21 @@ var product_costing_shipping_references_default = {
|
|
|
33670
34090
|
};
|
|
33671
34091
|
|
|
33672
34092
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
33673
|
-
var ShippingReferenceSchema =
|
|
33674
|
-
reference:
|
|
33675
|
-
min:
|
|
33676
|
-
max:
|
|
33677
|
-
updatedAt:
|
|
33678
|
-
confidence:
|
|
34093
|
+
var ShippingReferenceSchema = z137.object({
|
|
34094
|
+
reference: z137.number().positive(),
|
|
34095
|
+
min: z137.number().nonnegative(),
|
|
34096
|
+
max: z137.number().positive(),
|
|
34097
|
+
updatedAt: z137.string().date(),
|
|
34098
|
+
confidence: z137.enum([
|
|
33679
34099
|
"high",
|
|
33680
34100
|
"medium",
|
|
33681
34101
|
"medium-low"
|
|
33682
34102
|
]),
|
|
33683
|
-
sources:
|
|
34103
|
+
sources: z137.array(z137.string().url().startsWith("https://")).min(1).max(3)
|
|
33684
34104
|
}).superRefine(({ reference, min, max }, context) => {
|
|
33685
34105
|
if (min > reference || reference > max) {
|
|
33686
34106
|
context.addIssue({
|
|
33687
|
-
code:
|
|
34107
|
+
code: z137.ZodIssueCode.custom,
|
|
33688
34108
|
message: "shipping_reference_outside_range",
|
|
33689
34109
|
path: [
|
|
33690
34110
|
"reference"
|
|
@@ -33692,7 +34112,7 @@ var ShippingReferenceSchema = z136.object({
|
|
|
33692
34112
|
});
|
|
33693
34113
|
}
|
|
33694
34114
|
});
|
|
33695
|
-
var SHIPPING_REFERENCES =
|
|
34115
|
+
var SHIPPING_REFERENCES = z137.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
|
|
33696
34116
|
var PRODUCT_COSTING_COUNTRY_CODES = Object.freeze(Object.keys(SHIPPING_REFERENCES));
|
|
33697
34117
|
var SPANISH_LOCALE_COUNTRIES = /* @__PURE__ */ new Set([
|
|
33698
34118
|
"MX",
|
|
@@ -33874,18 +34294,18 @@ function getProductCostingCountryName(country) {
|
|
|
33874
34294
|
__name(getProductCostingCountryName, "getProductCostingCountryName");
|
|
33875
34295
|
|
|
33876
34296
|
// ../../packages/product-economics/src/product-costing.ts
|
|
33877
|
-
var ProductCostingInputSchema =
|
|
33878
|
-
country:
|
|
33879
|
-
supplierCost:
|
|
33880
|
-
shippingCost:
|
|
33881
|
-
returnRate:
|
|
33882
|
-
cancellationRate:
|
|
33883
|
-
adsManagerCpa:
|
|
33884
|
-
desiredMargin:
|
|
34297
|
+
var ProductCostingInputSchema = z138.object({
|
|
34298
|
+
country: z138.string().refine(isProductCostingCountryCode, "unsupported_country"),
|
|
34299
|
+
supplierCost: z138.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
|
|
34300
|
+
shippingCost: z138.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
|
|
34301
|
+
returnRate: z138.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
34302
|
+
cancellationRate: z138.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
34303
|
+
adsManagerCpa: z138.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
|
|
34304
|
+
desiredMargin: z138.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
|
|
33885
34305
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
33886
34306
|
if (returnRate + cancellationRate >= 1) {
|
|
33887
34307
|
context.addIssue({
|
|
33888
|
-
code:
|
|
34308
|
+
code: z138.ZodIssueCode.custom,
|
|
33889
34309
|
message: "delivery_rate_positive",
|
|
33890
34310
|
path: [
|
|
33891
34311
|
"cancellationRate"
|
|
@@ -33982,15 +34402,15 @@ function calculateProductCosting(rawInput) {
|
|
|
33982
34402
|
__name(calculateProductCosting, "calculateProductCosting");
|
|
33983
34403
|
|
|
33984
34404
|
// src/tools/product-costing.ts
|
|
33985
|
-
import { z as
|
|
34405
|
+
import { z as z139 } from "zod";
|
|
33986
34406
|
var costProductGuidance = getProductMakerCapabilityModelGuidance("cost_product");
|
|
33987
|
-
var optionalAmount = /* @__PURE__ */ __name((description) =>
|
|
33988
|
-
var optionalPercent = /* @__PURE__ */ __name((description) =>
|
|
33989
|
-
var ProductCostingToolInput =
|
|
33990
|
-
country:
|
|
34407
|
+
var optionalAmount = /* @__PURE__ */ __name((description) => z139.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
|
|
34408
|
+
var optionalPercent = /* @__PURE__ */ __name((description) => z139.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
|
|
34409
|
+
var ProductCostingToolInput = z139.object({
|
|
34410
|
+
country: z139.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
33991
34411
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
33992
34412
|
}).optional().describe("C\xF3digo ISO-2 de cualquiera de los pa\xEDses disponibles en ProductMaker. Omite para Colombia."),
|
|
33993
|
-
supplierCost:
|
|
34413
|
+
supplierCost: z139.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."),
|
|
33994
34414
|
supplierCostCop: optionalAmount("Alias anterior para costo del proveedor en Colombia. Prefiere supplierCost."),
|
|
33995
34415
|
shippingCost: optionalAmount("Costo de un env\xEDo en la moneda del pa\xEDs. Omite para usar el valor gu\xEDa vigente."),
|
|
33996
34416
|
shippingCostCop: optionalAmount("Alias anterior para flete en Colombia. Prefiere shippingCost."),
|
|
@@ -34153,7 +34573,7 @@ function formatPercent(value) {
|
|
|
34153
34573
|
__name(formatPercent, "formatPercent");
|
|
34154
34574
|
|
|
34155
34575
|
// src/tools/product-research.ts
|
|
34156
|
-
import { z as
|
|
34576
|
+
import { z as z140 } from "zod";
|
|
34157
34577
|
|
|
34158
34578
|
// src/tools/product-research-idempotency.ts
|
|
34159
34579
|
var RESEARCH_IDEMPOTENCY_WINDOW_MS = 2 * 60 * 60 * 1e3;
|
|
@@ -34524,17 +34944,17 @@ var TERMINAL2 = /* @__PURE__ */ new Set([
|
|
|
34524
34944
|
]);
|
|
34525
34945
|
var POLL_INTERVAL_MS = 5e3;
|
|
34526
34946
|
var MAX_WAIT_SECONDS = 120;
|
|
34527
|
-
var FindInput =
|
|
34947
|
+
var FindInput = z140.object({
|
|
34528
34948
|
targetCountry: ResearchTargetCountryEnum.describe("Pa\xEDs objetivo. S\xF3lo CO, MX, PE, EC y CL tienen cobertura de investigaci\xF3n."),
|
|
34529
34949
|
categoryKey: ResearchCategoryEnum.default("auto").describe('Categor\xEDa a investigar. Usa "auto" para que la IA elija seg\xFAn el mercado.'),
|
|
34530
|
-
confirmed:
|
|
34531
|
-
waitSeconds:
|
|
34950
|
+
confirmed: z140.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
|
|
34951
|
+
waitSeconds: z140.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
|
|
34532
34952
|
});
|
|
34533
|
-
var GetInput =
|
|
34534
|
-
runId:
|
|
34953
|
+
var GetInput = z140.object({
|
|
34954
|
+
runId: z140.string().uuid().describe("ID del run devuelto por find_winning_products.")
|
|
34535
34955
|
});
|
|
34536
|
-
var ListInput =
|
|
34537
|
-
limit:
|
|
34956
|
+
var ListInput = z140.object({
|
|
34957
|
+
limit: z140.number().int().min(1).max(20).default(10)
|
|
34538
34958
|
});
|
|
34539
34959
|
function textResult(text3) {
|
|
34540
34960
|
return {
|
|
@@ -34673,17 +35093,17 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
|
|
|
34673
35093
|
__name(registerProductResearchTools, "registerProductResearchTools");
|
|
34674
35094
|
|
|
34675
35095
|
// src/tools/dropshipping-projects.ts
|
|
34676
|
-
import { z as
|
|
35096
|
+
import { z as z141 } from "zod";
|
|
34677
35097
|
var startDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("start_dropshipping_project");
|
|
34678
35098
|
var costDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("cost_dropshipping_project");
|
|
34679
35099
|
var guideDropshippingLaunchGuidance = getProductMakerCapabilityModelGuidance("guide_dropshipping_launch");
|
|
34680
|
-
var ProjectId =
|
|
34681
|
-
var DropshippingProjectStatus =
|
|
35100
|
+
var ProjectId = z141.string().uuid();
|
|
35101
|
+
var DropshippingProjectStatus = z141.enum([
|
|
34682
35102
|
"active",
|
|
34683
35103
|
"completed",
|
|
34684
35104
|
"archived"
|
|
34685
35105
|
]);
|
|
34686
|
-
var DropshippingProjectPhase =
|
|
35106
|
+
var DropshippingProjectPhase = z141.enum([
|
|
34687
35107
|
"research",
|
|
34688
35108
|
"costing",
|
|
34689
35109
|
"media",
|
|
@@ -34692,21 +35112,21 @@ var DropshippingProjectPhase = z140.enum([
|
|
|
34692
35112
|
"advertising",
|
|
34693
35113
|
"complete"
|
|
34694
35114
|
]);
|
|
34695
|
-
var DropshippingRewardMilestone =
|
|
35115
|
+
var DropshippingRewardMilestone = z141.enum([
|
|
34696
35116
|
"product_selected",
|
|
34697
35117
|
"costing_saved",
|
|
34698
35118
|
"product_media_ready",
|
|
34699
35119
|
"creatives_completed",
|
|
34700
35120
|
"campaign_created"
|
|
34701
35121
|
]);
|
|
34702
|
-
var TargetCountry =
|
|
35122
|
+
var TargetCountry = z141.enum([
|
|
34703
35123
|
"CO",
|
|
34704
35124
|
"MX",
|
|
34705
35125
|
"PE",
|
|
34706
35126
|
"EC",
|
|
34707
35127
|
"CL"
|
|
34708
35128
|
]);
|
|
34709
|
-
var ResearchCategory =
|
|
35129
|
+
var ResearchCategory = z141.enum([
|
|
34710
35130
|
"auto",
|
|
34711
35131
|
"automotive",
|
|
34712
35132
|
"kitchen",
|
|
@@ -34721,7 +35141,7 @@ var ResearchCategory = z140.enum([
|
|
|
34721
35141
|
"garden",
|
|
34722
35142
|
"cleaning"
|
|
34723
35143
|
]);
|
|
34724
|
-
var HttpUrl3 =
|
|
35144
|
+
var HttpUrl3 = z141.string().url().max(2e3).refine((value) => {
|
|
34725
35145
|
try {
|
|
34726
35146
|
return [
|
|
34727
35147
|
"http:",
|
|
@@ -34731,45 +35151,45 @@ var HttpUrl3 = z140.string().url().max(2e3).refine((value) => {
|
|
|
34731
35151
|
return false;
|
|
34732
35152
|
}
|
|
34733
35153
|
}, "URL must use HTTP(S)");
|
|
34734
|
-
var ResearchCandidateOrigin =
|
|
34735
|
-
type:
|
|
35154
|
+
var ResearchCandidateOrigin = z141.object({
|
|
35155
|
+
type: z141.literal("research_candidate"),
|
|
34736
35156
|
runId: ProjectId,
|
|
34737
|
-
candidateSourceId:
|
|
35157
|
+
candidateSourceId: z141.string().min(1).max(160)
|
|
34738
35158
|
});
|
|
34739
|
-
var TaskOrigin =
|
|
34740
|
-
type:
|
|
35159
|
+
var TaskOrigin = z141.object({
|
|
35160
|
+
type: z141.literal("task"),
|
|
34741
35161
|
taskId: ProjectId
|
|
34742
35162
|
});
|
|
34743
|
-
var ManualOrigin =
|
|
34744
|
-
type:
|
|
35163
|
+
var ManualOrigin = z141.object({
|
|
35164
|
+
type: z141.literal("manual"),
|
|
34745
35165
|
clientRequestId: ProjectId,
|
|
34746
|
-
country:
|
|
35166
|
+
country: z141.string().min(2).max(3).optional()
|
|
34747
35167
|
});
|
|
34748
|
-
var StartProjectInput =
|
|
34749
|
-
origin:
|
|
35168
|
+
var StartProjectInput = z141.object({
|
|
35169
|
+
origin: z141.discriminatedUnion("type", [
|
|
34750
35170
|
ResearchCandidateOrigin,
|
|
34751
35171
|
TaskOrigin,
|
|
34752
35172
|
ManualOrigin
|
|
34753
35173
|
]),
|
|
34754
|
-
productName:
|
|
35174
|
+
productName: z141.string().trim().min(1).max(240).optional(),
|
|
34755
35175
|
productUrl: HttpUrl3.optional(),
|
|
34756
|
-
country:
|
|
34757
|
-
languageCode:
|
|
35176
|
+
country: z141.string().min(2).max(3).optional(),
|
|
35177
|
+
languageCode: z141.string().min(2).max(16).optional()
|
|
34758
35178
|
}).strict();
|
|
34759
|
-
var CostProjectInput =
|
|
35179
|
+
var CostProjectInput = z141.object({
|
|
34760
35180
|
projectId: ProjectId,
|
|
34761
|
-
version:
|
|
34762
|
-
country:
|
|
35181
|
+
version: z141.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
|
|
35182
|
+
country: z141.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
34763
35183
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
34764
35184
|
}).describe("C\xF3digo ISO-2 del pa\xEDs del proyecto. Usa el `targetCountry` que devuelve el proyecto."),
|
|
34765
|
-
supplierCost:
|
|
34766
|
-
shippingCost:
|
|
34767
|
-
returnRate:
|
|
34768
|
-
cancellationRate:
|
|
34769
|
-
adsManagerCpa:
|
|
34770
|
-
desiredMargin:
|
|
34771
|
-
});
|
|
34772
|
-
var GuideInput =
|
|
35185
|
+
supplierCost: z141.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."),
|
|
35186
|
+
shippingCost: z141.number().finite().nonnegative().optional().describe("Costo de un env\xEDo. Omite para usar el valor gu\xEDa del pa\xEDs en vez de inventarlo."),
|
|
35187
|
+
returnRate: z141.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."),
|
|
35188
|
+
cancellationRate: z141.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."),
|
|
35189
|
+
adsManagerCpa: z141.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
|
|
35190
|
+
desiredMargin: z141.number().finite().min(0).lt(1).optional().describe("Margen deseado (0.1 = 10%). Omite para usar el valor gu\xEDa del pa\xEDs.")
|
|
35191
|
+
});
|
|
35192
|
+
var GuideInput = z141.object({
|
|
34773
35193
|
projectId: ProjectId.optional()
|
|
34774
35194
|
}).strict();
|
|
34775
35195
|
var NEXT_ACTION_KINDS = [
|
|
@@ -34787,29 +35207,29 @@ var NEXT_ACTION_KINDS = [
|
|
|
34787
35207
|
"repair_meta_campaign",
|
|
34788
35208
|
"review_paused_campaign"
|
|
34789
35209
|
];
|
|
34790
|
-
var DropshippingProjectNextAction =
|
|
34791
|
-
kind:
|
|
34792
|
-
href:
|
|
35210
|
+
var DropshippingProjectNextAction = z141.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z141.object({
|
|
35211
|
+
kind: z141.literal(kind),
|
|
35212
|
+
href: z141.string().min(1)
|
|
34793
35213
|
})));
|
|
34794
|
-
var CostingInputSchema =
|
|
34795
|
-
country:
|
|
34796
|
-
supplierCost:
|
|
34797
|
-
shippingCost:
|
|
34798
|
-
returnRate:
|
|
34799
|
-
cancellationRate:
|
|
34800
|
-
adsManagerCpa:
|
|
34801
|
-
desiredMargin:
|
|
35214
|
+
var CostingInputSchema = z141.object({
|
|
35215
|
+
country: z141.string().min(2).max(3),
|
|
35216
|
+
supplierCost: z141.number().finite().positive(),
|
|
35217
|
+
shippingCost: z141.number().finite().nonnegative(),
|
|
35218
|
+
returnRate: z141.number().finite().min(0).lt(1),
|
|
35219
|
+
cancellationRate: z141.number().finite().min(0).lt(1),
|
|
35220
|
+
adsManagerCpa: z141.number().finite().nonnegative(),
|
|
35221
|
+
desiredMargin: z141.number().finite().min(0).lt(1)
|
|
34802
35222
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
34803
35223
|
if (returnRate + cancellationRate >= 1) context.addIssue({
|
|
34804
|
-
code:
|
|
35224
|
+
code: z141.ZodIssueCode.custom,
|
|
34805
35225
|
path: [
|
|
34806
35226
|
"cancellationRate"
|
|
34807
35227
|
]
|
|
34808
35228
|
});
|
|
34809
35229
|
});
|
|
34810
|
-
var FiniteCostingNumber =
|
|
34811
|
-
var CostingResultSchema =
|
|
34812
|
-
country:
|
|
35230
|
+
var FiniteCostingNumber = z141.number().finite();
|
|
35231
|
+
var CostingResultSchema = z141.object({
|
|
35232
|
+
country: z141.string().min(2).max(3),
|
|
34813
35233
|
deliveryRate: FiniteCostingNumber,
|
|
34814
35234
|
adjustedShippingCost: FiniteCostingNumber,
|
|
34815
35235
|
adjustedCpa: FiniteCostingNumber,
|
|
@@ -34822,45 +35242,45 @@ var CostingResultSchema = z140.object({
|
|
|
34822
35242
|
estimatedProfit: FiniteCostingNumber,
|
|
34823
35243
|
actualMargin: FiniteCostingNumber,
|
|
34824
35244
|
breakEvenAdsManagerCpa: FiniteCostingNumber,
|
|
34825
|
-
wasPriceAutoAdjusted:
|
|
34826
|
-
profitabilityStatus:
|
|
34827
|
-
});
|
|
34828
|
-
var RewardProgressSchema =
|
|
34829
|
-
campaignKey:
|
|
34830
|
-
totalCredits:
|
|
34831
|
-
earnedCredits:
|
|
34832
|
-
milestones:
|
|
35245
|
+
wasPriceAutoAdjusted: z141.boolean(),
|
|
35246
|
+
profitabilityStatus: z141.literal("healthy")
|
|
35247
|
+
});
|
|
35248
|
+
var RewardProgressSchema = z141.object({
|
|
35249
|
+
campaignKey: z141.literal("dropshipping-launch-v1"),
|
|
35250
|
+
totalCredits: z141.number().int().positive(),
|
|
35251
|
+
earnedCredits: z141.number().int().nonnegative(),
|
|
35252
|
+
milestones: z141.array(z141.object({
|
|
34833
35253
|
milestone: DropshippingRewardMilestone,
|
|
34834
|
-
credits:
|
|
34835
|
-
available:
|
|
34836
|
-
earned:
|
|
35254
|
+
credits: z141.number().int().positive(),
|
|
35255
|
+
available: z141.boolean().optional(),
|
|
35256
|
+
earned: z141.boolean(),
|
|
34837
35257
|
grantId: ProjectId.nullable(),
|
|
34838
|
-
grantedAt:
|
|
35258
|
+
grantedAt: z141.string().datetime().nullable()
|
|
34839
35259
|
})).length(DropshippingRewardMilestone.options.length)
|
|
34840
35260
|
});
|
|
34841
|
-
var ProjectResponseSchema =
|
|
35261
|
+
var ProjectResponseSchema = z141.object({
|
|
34842
35262
|
id: ProjectId,
|
|
34843
35263
|
taskId: ProjectId.nullable(),
|
|
34844
35264
|
status: DropshippingProjectStatus,
|
|
34845
|
-
originKey:
|
|
35265
|
+
originKey: z141.string().min(1),
|
|
34846
35266
|
researchRunId: ProjectId.nullable(),
|
|
34847
|
-
candidateSourceId:
|
|
34848
|
-
productName:
|
|
35267
|
+
candidateSourceId: z141.string().nullable(),
|
|
35268
|
+
productName: z141.string().nullable(),
|
|
34849
35269
|
productUrl: HttpUrl3.nullable(),
|
|
34850
35270
|
referenceImageUrl: HttpUrl3.nullable(),
|
|
34851
|
-
targetCountry:
|
|
34852
|
-
languageCode:
|
|
34853
|
-
hasReferenceImage:
|
|
34854
|
-
hasWinnerReferenceImage:
|
|
35271
|
+
targetCountry: z141.string().nullable(),
|
|
35272
|
+
languageCode: z141.string().nullable(),
|
|
35273
|
+
hasReferenceImage: z141.boolean(),
|
|
35274
|
+
hasWinnerReferenceImage: z141.boolean(),
|
|
34855
35275
|
costingInput: CostingInputSchema.nullable(),
|
|
34856
35276
|
costingResult: CostingResultSchema.nullable(),
|
|
34857
|
-
costingVersion:
|
|
34858
|
-
version:
|
|
35277
|
+
costingVersion: z141.number().int().positive().nullable(),
|
|
35278
|
+
version: z141.number().int().positive(),
|
|
34859
35279
|
phase: DropshippingProjectPhase,
|
|
34860
35280
|
nextAction: DropshippingProjectNextAction.nullable(),
|
|
34861
35281
|
rewards: RewardProgressSchema,
|
|
34862
|
-
createdAt:
|
|
34863
|
-
updatedAt:
|
|
35282
|
+
createdAt: z141.string().datetime(),
|
|
35283
|
+
updatedAt: z141.string().datetime()
|
|
34864
35284
|
}).passthrough();
|
|
34865
35285
|
var NEXT_ACTION_GUIDANCE = {
|
|
34866
35286
|
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.",
|
|
@@ -34980,58 +35400,58 @@ function registerDropshippingProjectTools(server, api) {
|
|
|
34980
35400
|
__name(registerDropshippingProjectTools, "registerDropshippingProjectTools");
|
|
34981
35401
|
|
|
34982
35402
|
// src/tools/daily-control.ts
|
|
34983
|
-
import { z as
|
|
35403
|
+
import { z as z142 } from "zod";
|
|
34984
35404
|
var getDailyControlGuidance = getProductMakerCapabilityModelGuidance("get_daily_control");
|
|
34985
35405
|
var linkCampaignToProjectGuidance = getProductMakerCapabilityModelGuidance("link_campaign_to_project");
|
|
34986
35406
|
var reportDailyReturnsGuidance = getProductMakerCapabilityModelGuidance("report_daily_returns");
|
|
34987
|
-
var ProviderCampaignIdentifier =
|
|
34988
|
-
var DateOnly =
|
|
34989
|
-
var DailyControlInput =
|
|
35407
|
+
var ProviderCampaignIdentifier = z142.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
|
|
35408
|
+
var DateOnly = z142.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
35409
|
+
var DailyControlInput = z142.object({
|
|
34990
35410
|
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."),
|
|
34991
|
-
days:
|
|
34992
|
-
projectId:
|
|
35411
|
+
days: z142.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
35412
|
+
projectId: z142.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
|
|
34993
35413
|
}).strict();
|
|
34994
|
-
var LinkCampaignInput =
|
|
34995
|
-
projectId:
|
|
34996
|
-
provider:
|
|
35414
|
+
var LinkCampaignInput = z142.object({
|
|
35415
|
+
projectId: z142.string().uuid(),
|
|
35416
|
+
provider: z142.enum([
|
|
34997
35417
|
"meta",
|
|
34998
35418
|
"tiktok"
|
|
34999
35419
|
]),
|
|
35000
35420
|
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."),
|
|
35001
35421
|
campaignId: ProviderCampaignIdentifier
|
|
35002
35422
|
}).strict();
|
|
35003
|
-
var ReportReturnsInput =
|
|
35004
|
-
projectId:
|
|
35423
|
+
var ReportReturnsInput = z142.object({
|
|
35424
|
+
projectId: z142.string().uuid(),
|
|
35005
35425
|
date: DateOnly,
|
|
35006
|
-
returnedOrders:
|
|
35007
|
-
note:
|
|
35008
|
-
}).strict();
|
|
35009
|
-
var DailyControlStatusMirror = DailyControlStatusEnum.or(
|
|
35010
|
-
var DailyControlLightMirror = DailyControlLightEnum.or(
|
|
35011
|
-
var DailyControlSourceMirror = DailyControlSourceEnum.or(
|
|
35012
|
-
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(
|
|
35013
|
-
var DailyControlDayMirror =
|
|
35014
|
-
date:
|
|
35015
|
-
returnedOrders:
|
|
35426
|
+
returnedOrders: z142.number().int().min(0).max(1e5),
|
|
35427
|
+
note: z142.string().trim().max(280).optional()
|
|
35428
|
+
}).strict();
|
|
35429
|
+
var DailyControlStatusMirror = DailyControlStatusEnum.or(z142.string());
|
|
35430
|
+
var DailyControlLightMirror = DailyControlLightEnum.or(z142.string());
|
|
35431
|
+
var DailyControlSourceMirror = DailyControlSourceEnum.or(z142.string());
|
|
35432
|
+
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z142.string());
|
|
35433
|
+
var DailyControlDayMirror = z142.object({
|
|
35434
|
+
date: z142.string(),
|
|
35435
|
+
returnedOrders: z142.number(),
|
|
35016
35436
|
returnedSource: DailyControlSourceMirror,
|
|
35017
35437
|
cancelledSource: DailyControlSourceMirror,
|
|
35018
|
-
hasEstimates:
|
|
35438
|
+
hasEstimates: z142.boolean(),
|
|
35019
35439
|
light: DailyControlLightMirror
|
|
35020
35440
|
}).passthrough();
|
|
35021
|
-
var DailyControlProductMirror =
|
|
35022
|
-
projectId:
|
|
35023
|
-
productName:
|
|
35441
|
+
var DailyControlProductMirror = z142.object({
|
|
35442
|
+
projectId: z142.string().uuid(),
|
|
35443
|
+
productName: z142.string().nullable(),
|
|
35024
35444
|
status: DailyControlStatusMirror,
|
|
35025
|
-
statusMessage:
|
|
35026
|
-
days:
|
|
35445
|
+
statusMessage: z142.string().nullable(),
|
|
35446
|
+
days: z142.array(DailyControlDayMirror),
|
|
35027
35447
|
verdict: DailyControlVerdictMirror.nullable(),
|
|
35028
|
-
rationale:
|
|
35448
|
+
rationale: z142.string().nullable()
|
|
35029
35449
|
}).passthrough();
|
|
35030
|
-
var DailyControlResponseMirror =
|
|
35031
|
-
since:
|
|
35032
|
-
until:
|
|
35033
|
-
products:
|
|
35034
|
-
archivedProjectSpend:
|
|
35450
|
+
var DailyControlResponseMirror = z142.object({
|
|
35451
|
+
since: z142.string(),
|
|
35452
|
+
until: z142.string(),
|
|
35453
|
+
products: z142.array(DailyControlProductMirror),
|
|
35454
|
+
archivedProjectSpend: z142.array(z142.unknown())
|
|
35035
35455
|
}).passthrough();
|
|
35036
35456
|
var MCP_WARNINGS_KEY = "_mcpDailyControlWarnings";
|
|
35037
35457
|
function withWarnings(response) {
|
|
@@ -35106,7 +35526,7 @@ __name(registerDailyControlTools, "registerDailyControlTools");
|
|
|
35106
35526
|
// src/tools/product-control.ts
|
|
35107
35527
|
import { readFile, stat } from "fs/promises";
|
|
35108
35528
|
import { basename as basename2, isAbsolute, resolve as resolve3 } from "path";
|
|
35109
|
-
import { z as
|
|
35529
|
+
import { z as z143 } from "zod";
|
|
35110
35530
|
var getProductControlGuidance = getProductMakerCapabilityModelGuidance("get_product_control");
|
|
35111
35531
|
var listImportableProductsGuidance = getProductMakerCapabilityModelGuidance("list_importable_products");
|
|
35112
35532
|
var importProductControlsGuidance = getProductMakerCapabilityModelGuidance("import_product_controls");
|
|
@@ -35119,36 +35539,36 @@ var createOperationGuidance = getProductMakerCapabilityModelGuidance("create_ope
|
|
|
35119
35539
|
var mergeProductsGuidance = getProductMakerCapabilityModelGuidance("merge_products");
|
|
35120
35540
|
var syncShopifyOrdersGuidance = getProductMakerCapabilityModelGuidance("sync_shopify_orders");
|
|
35121
35541
|
var importOrdersFileGuidance = getProductMakerCapabilityModelGuidance("import_orders_file");
|
|
35122
|
-
var DateOnly2 =
|
|
35542
|
+
var DateOnly2 = z143.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
35123
35543
|
var IMPORT_BATCH_MAX2 = 50;
|
|
35124
|
-
var ProductControlListInput =
|
|
35125
|
-
days:
|
|
35544
|
+
var ProductControlListInput = z143.object({
|
|
35545
|
+
days: z143.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
35126
35546
|
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."),
|
|
35127
|
-
shopDomain:
|
|
35547
|
+
shopDomain: z143.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
|
|
35128
35548
|
}).strict();
|
|
35129
|
-
var ImportableProductsInput =
|
|
35130
|
-
q:
|
|
35131
|
-
after:
|
|
35132
|
-
shopDomain:
|
|
35549
|
+
var ImportableProductsInput = z143.object({
|
|
35550
|
+
q: z143.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
|
|
35551
|
+
after: z143.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
|
|
35552
|
+
shopDomain: z143.string().min(1).optional()
|
|
35133
35553
|
}).strict();
|
|
35134
|
-
var ImportProductControlsInput =
|
|
35135
|
-
shopifyProductIds:
|
|
35554
|
+
var ImportProductControlsInput = z143.object({
|
|
35555
|
+
shopifyProductIds: z143.array(z143.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."),
|
|
35136
35556
|
// Obligatorio, como en el endpoint: con dos tiendas conectadas, importar
|
|
35137
35557
|
// sin decir a cuál archivaría el producto bajo la tienda equivocada.
|
|
35138
|
-
shopDomain:
|
|
35139
|
-
}).strict();
|
|
35140
|
-
var SetProductCostingInput =
|
|
35141
|
-
shopDomain:
|
|
35142
|
-
shopifyProductId:
|
|
35143
|
-
targetCountry:
|
|
35144
|
-
supplierCost:
|
|
35145
|
-
shippingCost:
|
|
35146
|
-
returnRate:
|
|
35147
|
-
cancellationRate:
|
|
35148
|
-
}).strict();
|
|
35149
|
-
var Count =
|
|
35150
|
-
var ReportProductCountsInput =
|
|
35151
|
-
productControlId:
|
|
35558
|
+
shopDomain: z143.string().min(1)
|
|
35559
|
+
}).strict();
|
|
35560
|
+
var SetProductCostingInput = z143.object({
|
|
35561
|
+
shopDomain: z143.string().min(1),
|
|
35562
|
+
shopifyProductId: z143.string().min(1).max(64),
|
|
35563
|
+
targetCountry: z143.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
|
|
35564
|
+
supplierCost: z143.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
|
|
35565
|
+
shippingCost: z143.number().finite().nonnegative(),
|
|
35566
|
+
returnRate: z143.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
|
|
35567
|
+
cancellationRate: z143.number().finite().min(0).lt(1)
|
|
35568
|
+
}).strict();
|
|
35569
|
+
var Count = z143.number().int().min(0).max(1e5).nullable().optional();
|
|
35570
|
+
var ReportProductCountsInput = z143.object({
|
|
35571
|
+
productControlId: z143.string().uuid().describe("El identificador que devuelve get_product_control."),
|
|
35152
35572
|
date: DateOnly2,
|
|
35153
35573
|
orders: Count.describe("Pedidos que entraron ese d\xEDa."),
|
|
35154
35574
|
cancelledOrders: Count,
|
|
@@ -35158,36 +35578,36 @@ var ReportProductCountsInput = z142.object({
|
|
|
35158
35578
|
}).strict();
|
|
35159
35579
|
var MAX_ORDERS_FILE_BYTES = 8 * 1024 * 1024;
|
|
35160
35580
|
var SyncShopifyOrdersInput = SyncShopifyOrdersSchema;
|
|
35161
|
-
var ImportOrdersFileInput =
|
|
35581
|
+
var ImportOrdersFileInput = z143.object({
|
|
35162
35582
|
/** Ruta ABSOLUTA en la máquina de quien usa el MCP. */
|
|
35163
|
-
path:
|
|
35164
|
-
operationId:
|
|
35583
|
+
path: z143.string().min(1),
|
|
35584
|
+
operationId: z143.string().uuid().optional(),
|
|
35165
35585
|
/** Solo mirar: devuelve el resumen y no escribe nada. */
|
|
35166
|
-
dryRun:
|
|
35586
|
+
dryRun: z143.boolean().optional()
|
|
35167
35587
|
}).strict();
|
|
35168
|
-
var CreateOperationInput =
|
|
35169
|
-
countryCode:
|
|
35170
|
-
label:
|
|
35588
|
+
var CreateOperationInput = z143.object({
|
|
35589
|
+
countryCode: z143.string().length(2),
|
|
35590
|
+
label: z143.string().trim().min(1).max(60).optional()
|
|
35171
35591
|
}).strict();
|
|
35172
|
-
var MergeProductsInput =
|
|
35173
|
-
sourceId:
|
|
35174
|
-
targetId:
|
|
35592
|
+
var MergeProductsInput = z143.object({
|
|
35593
|
+
sourceId: z143.string().uuid(),
|
|
35594
|
+
targetId: z143.string().uuid()
|
|
35175
35595
|
}).strict();
|
|
35176
|
-
var SetMonthlyExpenseInput =
|
|
35177
|
-
month:
|
|
35596
|
+
var SetMonthlyExpenseInput = z143.object({
|
|
35597
|
+
month: z143.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
35178
35598
|
label: SaveMonthlyExpenseSchema.shape.label,
|
|
35179
|
-
amount:
|
|
35180
|
-
operationId:
|
|
35599
|
+
amount: z143.number().finite().min(0),
|
|
35600
|
+
operationId: z143.string().uuid().optional()
|
|
35181
35601
|
}).strict();
|
|
35182
|
-
var SetAdSpendInput =
|
|
35183
|
-
month:
|
|
35184
|
-
operationId:
|
|
35602
|
+
var SetAdSpendInput = z143.object({
|
|
35603
|
+
month: z143.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
35604
|
+
operationId: z143.string().uuid().optional(),
|
|
35185
35605
|
/** null RETIRA la corrección; cero afirma que no pautó. */
|
|
35186
|
-
amount:
|
|
35606
|
+
amount: z143.number().finite().min(0).nullable()
|
|
35187
35607
|
}).strict();
|
|
35188
|
-
var GetFinancesInput =
|
|
35189
|
-
month:
|
|
35190
|
-
operationId:
|
|
35608
|
+
var GetFinancesInput = z143.object({
|
|
35609
|
+
month: z143.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."),
|
|
35610
|
+
operationId: z143.string().uuid().optional().describe("El negocio, si tiene mas de uno. Con uno solo no hace falta decirlo.")
|
|
35191
35611
|
}).strict();
|
|
35192
35612
|
function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
35193
35613
|
server.registerTool("get_product_control", {
|
|
@@ -35379,28 +35799,28 @@ function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
|
35379
35799
|
__name(registerProductControlTools, "registerProductControlTools");
|
|
35380
35800
|
|
|
35381
35801
|
// src/tools/market-study-estimate.ts
|
|
35382
|
-
import { z as
|
|
35802
|
+
import { z as z144 } from "zod";
|
|
35383
35803
|
var estimateMarketStudyGuidance = getProductMakerCapabilityModelGuidance("estimate_market_study_cost");
|
|
35384
|
-
var ProductTaskOutputEnum =
|
|
35804
|
+
var ProductTaskOutputEnum = z144.enum([
|
|
35385
35805
|
"landing",
|
|
35386
35806
|
"video",
|
|
35387
35807
|
"image"
|
|
35388
35808
|
]);
|
|
35389
|
-
var EstimateMarketStudyInput =
|
|
35390
|
-
kind:
|
|
35809
|
+
var EstimateMarketStudyInput = z144.object({
|
|
35810
|
+
kind: z144.enum([
|
|
35391
35811
|
"video",
|
|
35392
35812
|
"product_task"
|
|
35393
35813
|
]).describe('"video" para generate_video_creative; "product_task" para create_product_task.'),
|
|
35394
|
-
videoAngleCount:
|
|
35395
|
-
durationSeconds:
|
|
35814
|
+
videoAngleCount: z144.number().int().min(1).max(3).describe("Los mismos 1, 2 o 3 videos que vas a pedir al crear."),
|
|
35815
|
+
durationSeconds: z144.number().int().min(4).max(30).default(15).describe("La misma duraci\xF3n que enviar\xE1s al crear."),
|
|
35396
35816
|
videoStructure: VideoStructureEnum.default("single_take"),
|
|
35397
35817
|
videoQuality: VideoQualityEnum.default("economy"),
|
|
35398
35818
|
videoResolution: VideoResolutionEnum.default("480p"),
|
|
35399
|
-
productImageCount:
|
|
35819
|
+
productImageCount: z144.number().int().min(1).max(5).optional().describe("Cantidad de fotos del producto que adjuntar\xE1s (1-5)."),
|
|
35400
35820
|
outputs: ProductTaskOutputEnum.array().min(1).max(3).optional().describe('Solo para kind="product_task": los mismos outputs de create_product_task. Default: todos.'),
|
|
35401
|
-
generateAiMusic:
|
|
35821
|
+
generateAiMusic: z144.boolean().optional(),
|
|
35402
35822
|
generateAiEdit: AiEditRequestSchema.optional(),
|
|
35403
|
-
replicateWinnerWhenFound:
|
|
35823
|
+
replicateWinnerWhenFound: z144.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.")
|
|
35404
35824
|
}).strict();
|
|
35405
35825
|
function buildMarketStudyEstimateRequests(input) {
|
|
35406
35826
|
const quotesVideo = input.kind === "video" || (input.outputs ?? [
|
|
@@ -35539,6 +35959,7 @@ function createServer(opts) {
|
|
|
35539
35959
|
});
|
|
35540
35960
|
registerProductMakerPrompts(server);
|
|
35541
35961
|
registerMediaUploadAppResource(server, api.publicUrl("/v1/uploaded-assets/sessions/resolve"));
|
|
35962
|
+
registerTaskResultsAppResource(server, proxyBaseUrl);
|
|
35542
35963
|
registerProductCostingTools(server);
|
|
35543
35964
|
registerProductResearchTools(server, api);
|
|
35544
35965
|
registerDropshippingProjectTools(server, api);
|