@pixeldojo/mcp 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +83 -22
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +83 -22
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +83 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +83 -22
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -258,7 +258,7 @@ var init_generate = __esm({
|
|
|
258
258
|
InputSchema = z.object({
|
|
259
259
|
prompt: z.string().min(1).max(8e3).describe("Prompt describing what to generate."),
|
|
260
260
|
model: z.string().optional().describe(
|
|
261
|
-
'Override the model. Any apiId from /api/v1/models (e.g. "flux", "google-nano-banana", "veo-3.1", "kling-video"). Omit to use the default.'
|
|
261
|
+
'Override the model. Any apiId from /api/v1/models (e.g. "flux", "google-nano-banana", "veo-3.1-fast", "kling-video-v3-standard-text"). Omit to use the default.'
|
|
262
262
|
),
|
|
263
263
|
preset: z.string().optional().describe(
|
|
264
264
|
'Preset slug to seed the params (e.g. "cinematic-portrait", "product-floating-clean", "magazine-cover-text"). Browse the catalog at https://pixeldojo.ai/presets. Explicit fields override preset values.'
|
|
@@ -277,7 +277,7 @@ var init_generate = __esm({
|
|
|
277
277
|
prompt: { type: "string", description: "Prompt describing what to generate." },
|
|
278
278
|
model: {
|
|
279
279
|
type: "string",
|
|
280
|
-
description: 'Override the model. Any apiId from /api/v1/models (e.g. "flux", "google-nano-banana", "veo-3.1", "kling-video"). Omit to use the default.'
|
|
280
|
+
description: 'Override the model. Any apiId from /api/v1/models (e.g. "flux", "google-nano-banana", "veo-3.1-fast", "kling-video-v3-standard-text"). Omit to use the default.'
|
|
281
281
|
},
|
|
282
282
|
preset: {
|
|
283
283
|
type: "string",
|
|
@@ -471,17 +471,22 @@ async function run3(input, ctx) {
|
|
|
471
471
|
};
|
|
472
472
|
}
|
|
473
473
|
const apiId = requested;
|
|
474
|
-
if ((apiId
|
|
474
|
+
if (REQUIRES_REFERENCE.has(apiId) && !input.reference_image_url) {
|
|
475
475
|
return {
|
|
476
476
|
kind: "text",
|
|
477
|
-
text: `pixeldojo:character with model="${apiId}" requires reference_image_url (the source image of the character to edit). For generation from a prompt alone, use model="
|
|
477
|
+
text: `pixeldojo:character with model="${apiId}" requires reference_image_url (the source image of the character to edit). For generation from a prompt alone, use model="${DEFAULT_MODEL3}".`
|
|
478
478
|
};
|
|
479
479
|
}
|
|
480
480
|
const body = { prompt: input.prompt };
|
|
481
|
-
if (input.aspect_ratio) body.aspect_ratio = input.aspect_ratio;
|
|
482
481
|
if (input.reference_image_url) {
|
|
483
|
-
|
|
484
|
-
|
|
482
|
+
if (apiId === "flux-edit") {
|
|
483
|
+
body.input_image = input.reference_image_url;
|
|
484
|
+
} else {
|
|
485
|
+
body.image_urls = [input.reference_image_url];
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
if (input.aspect_ratio && apiId === "flux-edit" && FLUX_EDIT_ASPECT_RATIOS.has(input.aspect_ratio)) {
|
|
489
|
+
body.aspect_ratio = input.aspect_ratio;
|
|
485
490
|
}
|
|
486
491
|
const submitted = await ctx.client.run(apiId, body);
|
|
487
492
|
const result = await pollJobUntilDoneOrHandoff(
|
|
@@ -498,20 +503,35 @@ async function run3(input, ctx) {
|
|
|
498
503
|
(urls) => urls.length === 0 ? `Job ${submitted.jobId} completed but returned no assets.` : `Character shot ready. Asset: ${urls[0]}`
|
|
499
504
|
);
|
|
500
505
|
}
|
|
501
|
-
var ALLOWED, DEFAULT_MODEL3, InputSchema3, InputJsonSchema3, characterSkill;
|
|
506
|
+
var ALLOWED, DEFAULT_MODEL3, REQUIRES_REFERENCE, FLUX_EDIT_ASPECT_RATIOS, InputSchema3, InputJsonSchema3, characterSkill;
|
|
502
507
|
var init_character = __esm({
|
|
503
508
|
"src/skills/character.ts"() {
|
|
504
509
|
init_poll();
|
|
505
510
|
init_types();
|
|
506
|
-
ALLOWED = ["
|
|
507
|
-
DEFAULT_MODEL3 = "
|
|
511
|
+
ALLOWED = ["seedream-5", "seedream-4", "flux-edit", "gpt-image-2-edit"];
|
|
512
|
+
DEFAULT_MODEL3 = "seedream-5";
|
|
513
|
+
REQUIRES_REFERENCE = /* @__PURE__ */ new Set(["flux-edit", "gpt-image-2-edit"]);
|
|
514
|
+
FLUX_EDIT_ASPECT_RATIOS = /* @__PURE__ */ new Set([
|
|
515
|
+
"1:1",
|
|
516
|
+
"16:9",
|
|
517
|
+
"9:16",
|
|
518
|
+
"21:9",
|
|
519
|
+
"9:21",
|
|
520
|
+
"3:2",
|
|
521
|
+
"2:3",
|
|
522
|
+
"4:5",
|
|
523
|
+
"5:4",
|
|
524
|
+
"3:4",
|
|
525
|
+
"4:3",
|
|
526
|
+
"match_input_image"
|
|
527
|
+
]);
|
|
508
528
|
InputSchema3 = z.object({
|
|
509
529
|
prompt: z.string().min(1).max(8e3),
|
|
510
530
|
model: z.string().optional().describe(`One of: ${ALLOWED.join(", ")}. Defaults to ${DEFAULT_MODEL3}.`),
|
|
511
531
|
reference_image_url: z.string().url().optional().describe(
|
|
512
|
-
"Reference image of the character. Required by flux-edit and gpt-image-2-edit; optional for
|
|
532
|
+
"Reference image of the character. Required by flux-edit and gpt-image-2-edit; optional for seedream-5/seedream-4."
|
|
513
533
|
),
|
|
514
|
-
aspect_ratio: z.string().optional()
|
|
534
|
+
aspect_ratio: z.string().optional().describe('Only honored for model="flux-edit".')
|
|
515
535
|
});
|
|
516
536
|
InputJsonSchema3 = {
|
|
517
537
|
type: "object",
|
|
@@ -529,7 +549,7 @@ var init_character = __esm({
|
|
|
529
549
|
};
|
|
530
550
|
characterSkill = {
|
|
531
551
|
name: "pixeldojo:character",
|
|
532
|
-
description: "Generate or edit consistent characters across shots. Pass a reference_image_url for
|
|
552
|
+
description: "Generate or edit consistent characters across shots. Pass a reference_image_url for identity locking (seedream-5 by default).",
|
|
533
553
|
inputZod: InputSchema3,
|
|
534
554
|
inputJsonSchema: InputJsonSchema3,
|
|
535
555
|
allowedModels: [...ALLOWED],
|
|
@@ -570,8 +590,13 @@ var init_storyboard = __esm({
|
|
|
570
590
|
"src/skills/storyboard.ts"() {
|
|
571
591
|
init_poll();
|
|
572
592
|
init_types();
|
|
573
|
-
ALLOWED2 = [
|
|
574
|
-
|
|
593
|
+
ALLOWED2 = [
|
|
594
|
+
"veo-3.1-fast",
|
|
595
|
+
"veo-3.1-standard",
|
|
596
|
+
"kling-video-v3-standard-text",
|
|
597
|
+
"seedance-2-high"
|
|
598
|
+
];
|
|
599
|
+
DEFAULT_MODEL4 = "veo-3.1-fast";
|
|
575
600
|
InputSchema4 = z.object({
|
|
576
601
|
brief: z.string().min(1).max(8e3).describe("Storyboard brief: scene, shots, mood, action."),
|
|
577
602
|
model: z.string().optional().describe(`One of: ${ALLOWED2.join(", ")}. Defaults to ${DEFAULT_MODEL4}.`),
|
|
@@ -617,11 +642,20 @@ async function run5(input, ctx) {
|
|
|
617
642
|
const apiId = requested;
|
|
618
643
|
const body = {
|
|
619
644
|
prompt: "",
|
|
620
|
-
|
|
645
|
+
image: input.image_url
|
|
621
646
|
};
|
|
622
647
|
if (apiId === "magnific-upscaler") {
|
|
623
|
-
|
|
648
|
+
const allowed = [2, 4, 8, 16];
|
|
649
|
+
const requestedScale = input.scale_factor ?? 2;
|
|
650
|
+
const nearest = allowed.reduce(
|
|
651
|
+
(a, b) => Math.abs(b - requestedScale) < Math.abs(a - requestedScale) ? b : a
|
|
652
|
+
);
|
|
653
|
+
body.scale_factor = `${nearest}x`;
|
|
624
654
|
if (input.creativity !== void 0) body.creativity = input.creativity;
|
|
655
|
+
} else if (apiId === "creative-upscale") {
|
|
656
|
+
body.scale_factor = Math.min(10, Math.max(1, input.scale_factor ?? 2));
|
|
657
|
+
} else if (apiId === "face-enhance") {
|
|
658
|
+
body.scale_factor = Math.min(8, Math.max(1, input.scale_factor ?? 4));
|
|
625
659
|
}
|
|
626
660
|
const submitted = await ctx.client.run(apiId, body);
|
|
627
661
|
const result = await pollJobUntilDoneOrHandoff(
|
|
@@ -648,7 +682,9 @@ var init_upscale = __esm({
|
|
|
648
682
|
InputSchema5 = z.object({
|
|
649
683
|
image_url: z.string().url().describe("URL of the source image to upscale."),
|
|
650
684
|
model: z.string().optional().describe(`One of: ${ALLOWED3.join(", ")}. Defaults to ${DEFAULT_MODEL5}.`),
|
|
651
|
-
scale_factor: z.number().
|
|
685
|
+
scale_factor: z.number().min(1).max(16).optional().describe(
|
|
686
|
+
"Upscale multiplier. Magnific snaps to the nearest of 2/4/8/16 (default 2); creative-upscale accepts 1-10 (default 2); face-enhance accepts 1-8 (default 4)."
|
|
687
|
+
),
|
|
652
688
|
creativity: z.number().min(0).max(1).optional().describe("Magnific only: 0 (preserve) \u2192 1 (creative). Defaults to 0.")
|
|
653
689
|
});
|
|
654
690
|
InputJsonSchema5 = {
|
|
@@ -656,7 +692,7 @@ var init_upscale = __esm({
|
|
|
656
692
|
properties: {
|
|
657
693
|
image_url: { type: "string", format: "uri" },
|
|
658
694
|
model: { type: "string", enum: ALLOWED3 },
|
|
659
|
-
scale_factor: { type: "
|
|
695
|
+
scale_factor: { type: "number", minimum: 1, maximum: 16 },
|
|
660
696
|
creativity: { type: "number", minimum: 0, maximum: 1 }
|
|
661
697
|
},
|
|
662
698
|
required: ["image_url"]
|
|
@@ -1285,7 +1321,24 @@ async function runWorkflow(input, ctx) {
|
|
|
1285
1321
|
text: `Step ${i + 1} (${step.skill}) has invalid args: ${issue?.path.join(".") || "input"} ${issue?.message || "invalid"}.`
|
|
1286
1322
|
};
|
|
1287
1323
|
}
|
|
1288
|
-
|
|
1324
|
+
let result = await skill.run(parsed.data, ctx);
|
|
1325
|
+
if (result.kind === "handoff") {
|
|
1326
|
+
const handoffJobId = result.jobId;
|
|
1327
|
+
const polled = await pollJobUntilDoneOrHandoff(
|
|
1328
|
+
handoffJobId,
|
|
1329
|
+
(id) => ctx.client.getJob(id),
|
|
1330
|
+
ctx.buildStatusUrl,
|
|
1331
|
+
{
|
|
1332
|
+
syncBudgetMs: WORKFLOW_STEP_EXTRA_BUDGET_MS,
|
|
1333
|
+
now: ctx.pollOverrides?.now,
|
|
1334
|
+
sleep: ctx.pollOverrides?.sleep
|
|
1335
|
+
}
|
|
1336
|
+
);
|
|
1337
|
+
result = pollResultToSkillResult(
|
|
1338
|
+
polled,
|
|
1339
|
+
(urls) => urls.length === 0 ? `Job ${handoffJobId} completed but returned no assets.` : `Done. Asset: ${urls[0]}`
|
|
1340
|
+
);
|
|
1341
|
+
}
|
|
1289
1342
|
const url = firstUrl(result);
|
|
1290
1343
|
if (url) {
|
|
1291
1344
|
prevUrl = url;
|
|
@@ -1295,6 +1348,11 @@ async function runWorkflow(input, ctx) {
|
|
|
1295
1348
|
kind: "text",
|
|
1296
1349
|
text: `Workflow "${workflow.name}" stopped at step ${i + 1} (${step.skill}): ${result.text}`
|
|
1297
1350
|
};
|
|
1351
|
+
} else if (result.kind === "handoff") {
|
|
1352
|
+
return {
|
|
1353
|
+
kind: "text",
|
|
1354
|
+
text: `Workflow "${workflow.name}" is still on step ${i + 1} (${step.skill}) after an extended wait. Poll with pixeldojo:status { jobId: "${result.jobId}" }, then re-run the workflow once it completes.`
|
|
1355
|
+
};
|
|
1298
1356
|
} else {
|
|
1299
1357
|
outputs.push(`step ${i + 1} (${step.skill}): done (no asset URL)`);
|
|
1300
1358
|
}
|
|
@@ -1305,9 +1363,12 @@ async function runWorkflow(input, ctx) {
|
|
|
1305
1363
|
${outputs.join("\n")}`
|
|
1306
1364
|
};
|
|
1307
1365
|
}
|
|
1308
|
-
var StepSchema, SaveInputSchema, RunInputSchema, ListInputSchema, stepJson, saveWorkflowSkill, runWorkflowSkill, listWorkflowsSkill;
|
|
1366
|
+
var WORKFLOW_STEP_EXTRA_BUDGET_MS, StepSchema, SaveInputSchema, RunInputSchema, ListInputSchema, stepJson, saveWorkflowSkill, runWorkflowSkill, listWorkflowsSkill;
|
|
1309
1367
|
var init_workflows = __esm({
|
|
1310
1368
|
"src/skills/workflows.ts"() {
|
|
1369
|
+
init_poll();
|
|
1370
|
+
init_types();
|
|
1371
|
+
WORKFLOW_STEP_EXTRA_BUDGET_MS = 6e4;
|
|
1311
1372
|
StepSchema = z.object({
|
|
1312
1373
|
skill: z.string().regex(/^pixeldojo:(generate|edit|character|storyboard|upscale|audio|upload|from_url)$/, {
|
|
1313
1374
|
message: "Runnable skills only: generate, edit, character, storyboard, upscale, audio, upload, from_url."
|
|
@@ -1492,7 +1553,7 @@ function makeRedactedLogger(target = console) {
|
|
|
1492
1553
|
}
|
|
1493
1554
|
|
|
1494
1555
|
// src/server.ts
|
|
1495
|
-
var PACKAGE_VERSION = "0.
|
|
1556
|
+
var PACKAGE_VERSION = "0.6.0" ;
|
|
1496
1557
|
function buildServer(options) {
|
|
1497
1558
|
if (!options.apiKey) {
|
|
1498
1559
|
throw new Error(
|