@pixeldojo/mcp 0.16.0 → 0.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -460,6 +460,14 @@ function buildPayload(apiId, input, src, slot, audioSlot) {
460
460
  async function run(input, ctx) {
461
461
  const paramsGate = paramsWithoutModel(input.params, input.model);
462
462
  if (paramsGate) return { kind: "text", text: paramsGate };
463
+ if (input.upgrade_draft) return upgradeDraft(input, ctx);
464
+ if (input.draft && input.model && input.model !== DRAFT_MODEL) {
465
+ return {
466
+ kind: "text",
467
+ text: `Draft mode runs on ${DRAFT_MODEL} only. Drop model (or set it to ${DRAFT_MODEL}) to render a 480p draft.`
468
+ };
469
+ }
470
+ if (input.draft) input = { ...input, model: DRAFT_MODEL, resolution: DRAFT_RESOLUTION };
463
471
  let resolved = input;
464
472
  let referenceUrls = [];
465
473
  try {
@@ -521,6 +529,8 @@ async function run(input, ctx) {
521
529
  }
522
530
  const body = buildPayload(apiId, resolved, src, refField, audioSlot);
523
531
  const paramsNote = applyParams(body, input.params, input.model, apiId);
532
+ const draftDuration = input.draft ? Number(body.duration ?? DRAFT_DEFAULT_DURATION) : void 0;
533
+ if (input.draft) Object.assign(body, { draft: true, resolution: DRAFT_RESOLUTION, duration: draftDuration });
524
534
  const note = [routeNote, paramsNote].filter(Boolean).join(" ");
525
535
  const submitted = await ctx.client.run(apiId, body);
526
536
  const result = await pollJobUntilDoneOrHandoff(
@@ -532,15 +542,45 @@ async function run(input, ctx) {
532
542
  sleep: ctx.pollOverrides?.sleep
533
543
  }
534
544
  );
535
- return prefixNote(
545
+ const out = prefixNote(
536
546
  pollResultToSkillResult(
537
547
  result,
538
548
  (urls) => urls.length === 0 ? `Job ${submitted.jobId} completed but returned no assets.` : urls.length === 1 ? `Generated. Asset: ${urls[0]}` : `Generated ${urls.length} assets. URLs: ${urls.join(", ")}`
539
549
  ),
540
550
  note
541
551
  );
552
+ return draftDuration === void 0 ? out : { ...out, text: `${out.text}
553
+
554
+ ${draftLine(submitted.jobId, draftDuration)}` };
555
+ }
556
+ function draftLine(jobId, duration) {
557
+ return `This is a 480p draft (draft_job_id: ${jobId}, duration: ${duration}). When the user likes it, call pixeldojo_generate with {"upgrade_draft": "${jobId}", "duration": ${duration}} to render the same take at ${DRAFT_FINAL_RESOLUTION} (billed as a ${DRAFT_FINAL_RESOLUTION} run; upgrade it within a day).`;
558
+ }
559
+ async function upgradeDraft(input, ctx) {
560
+ if (input.duration === void 0) {
561
+ return {
562
+ kind: "text",
563
+ text: `upgrade_draft also needs duration: the draft's own length (its reply says "duration: N"; ${DRAFT_DEFAULT_DURATION} when it was made without one).`
564
+ };
565
+ }
566
+ const submitted = await ctx.client.run(DRAFT_MODEL, {
567
+ draft_job_id: input.upgrade_draft,
568
+ resolution: DRAFT_FINAL_RESOLUTION,
569
+ duration: input.duration
570
+ });
571
+ const result = await pollJobUntilDoneOrHandoff(submitted.jobId, (id) => ctx.client.getJob(id), ctx.buildStatusUrl, {
572
+ now: ctx.pollOverrides?.now,
573
+ sleep: ctx.pollOverrides?.sleep
574
+ });
575
+ return prefixNote(
576
+ pollResultToSkillResult(
577
+ result,
578
+ (urls) => urls.length === 0 ? `Job ${submitted.jobId} completed but returned no assets.` : `Upgraded to ${DRAFT_FINAL_RESOLUTION}. Asset: ${urls[0]}`
579
+ ),
580
+ `Rendering draft ${input.upgrade_draft} at ${DRAFT_FINAL_RESOLUTION}.`
581
+ );
542
582
  }
543
- var InputSchema, DEFAULT_MODEL, VIDEO_REFERENCE_MODEL, VIDEO_REFERENCE_SLOTS, VIDEO_INPUT_MODELS, InputJsonSchema, generateSkill;
583
+ var DRAFT_MODEL, DRAFT_RESOLUTION, DRAFT_FINAL_RESOLUTION, DRAFT_DEFAULT_DURATION, DRAFT_DESCRIPTION, UPGRADE_DESCRIPTION, InputSchema, DEFAULT_MODEL, VIDEO_REFERENCE_MODEL, VIDEO_REFERENCE_SLOTS, VIDEO_INPUT_MODELS, InputJsonSchema, generateSkill;
544
584
  var init_generate = __esm({
545
585
  "src/skills/generate.ts"() {
546
586
  init_poll();
@@ -548,6 +588,12 @@ var init_generate = __esm({
548
588
  init_upload_helpers();
549
589
  init_schema_snap();
550
590
  init_params();
591
+ DRAFT_MODEL = "seedance-2-5";
592
+ DRAFT_RESOLUTION = "480p";
593
+ DRAFT_FINAL_RESOLUTION = "1080p";
594
+ DRAFT_DEFAULT_DURATION = 5;
595
+ DRAFT_DESCRIPTION = "Seedance 2.5 draft mode: render a cheap 480p draft (runs on seedance-2-5) so the user can try takes before paying for full resolution. The reply gives the draft's job id and duration; pass them to upgrade_draft to render that exact take at 1080p.";
596
+ UPGRADE_DESCRIPTION = "Job id of a finished Seedance 2.5 draft to render at 1080p, the same take with full detail. Also pass `duration` equal to the draft's (the draft reply states it). The draft's prompt and media are reused, so prompt and references are ignored. Billed as a 1080p run.";
551
597
  InputSchema = zod.z.object({
552
598
  prompt: zod.z.string().min(1).max(8e3).describe("Prompt describing what to generate."),
553
599
  model: zod.z.string().optional().describe(
@@ -566,6 +612,8 @@ var init_generate = __esm({
566
612
  "Source video clip to animate / restyle / extend. Use this for videos; image_url is for still frames. With no model, a clip runs on seedance-2-reference; a named model with no clip input is swapped for it and the result says so."
567
613
  ),
568
614
  params: ParamsInput,
615
+ draft: zod.z.boolean().optional().describe(DRAFT_DESCRIPTION),
616
+ upgrade_draft: zod.z.string().regex(/^[A-Za-z0-9_-]{1,128}$/).optional().describe(UPGRADE_DESCRIPTION),
569
617
  image_path: zod.z.string().min(1).optional().describe(
570
618
  "Absolute local file path to a reference image/video. The skill uploads it to PixelDojo first (24h temp storage) and then dispatches. Prefer this over image_url when the user has the file on disk."
571
619
  ),
@@ -619,6 +667,8 @@ var init_generate = __esm({
619
667
  description: "Source video clip to animate / restyle / extend. Use this for videos; image_url is for still frames. With no model, a clip runs on seedance-2-reference; a named model with no clip input is swapped for it and the result says so."
620
668
  },
621
669
  params: PARAMS_JSON_SCHEMA,
670
+ draft: { type: "boolean", description: DRAFT_DESCRIPTION },
671
+ upgrade_draft: { type: "string", description: UPGRADE_DESCRIPTION },
622
672
  image_urls: {
623
673
  type: "array",
624
674
  items: { type: "string", format: "uri" },
@@ -638,8 +688,8 @@ var init_generate = __esm({
638
688
  };
639
689
  generateSkill = {
640
690
  name: "pixeldojo_generate",
641
- description: "Generate an image or video from a prompt with any model in the PixelDojo catalog. With no `model`, a prompt runs on seedream-5, which makes still images only. For a video, name seedance-2-5, which works from a prompt alone or a starting image. If a provider refuses the content, retry once on wan-3-0-video (video) or seedream-5 (images), the least-restricted models. For a multi-shot film or a music video synced to a song use pixeldojo_film; to change, move or extend an existing clip use pixeldojo_video. These are the models the PixelDojo studios use; name another only when the user asks for it. References: `image_url`/`image_urls` for stills, `video_url` for a source clip, `image_path`/`image_paths` for absolute local files (uploaded to 24h temp storage first). A clip or an audio track URL with no `model` runs on seedance-2-reference; a named model that cannot read a clip is swapped for it and the result says so, while a named model with no audio input drops the track. Model-specific settings go in `params` alongside an explicit `model`. Returns asset URLs, or a jobId for pixeldojo_status when the job outlasts the 30s wait.",
642
- hostedDescription: "Generate an image or video from a prompt with any model in the PixelDojo catalog. With no `model`, a prompt runs on seedream-5, which makes still images only. For a video, name seedance-2-5, which works from a prompt alone or a starting image. If a provider refuses the content, retry once on wan-3-0-video (video) or seedream-5 (images), the least-restricted models. For a multi-shot film or a music video synced to a song use pixeldojo_film; to change, move or extend an existing clip use pixeldojo_video. These are the models the PixelDojo studios use; name another only when the user asks for it. References: `image_url`/`image_urls` for stills and `video_url` for a source clip, all public http(s) URLs. A clip or an audio track URL with no `model` runs on seedance-2-reference; a named model that cannot read a clip is swapped for it and the result says so, while a named model with no audio input drops the track. Model-specific settings go in `params` alongside an explicit `model`. Returns asset URLs, or a jobId for pixeldojo_status when the job outlasts the 30s wait.",
691
+ description: "Generate an image or video from a prompt with any model in the PixelDojo catalog. With no `model`, a prompt runs on seedream-5, which makes still images only. For a video, name seedance-2-5, which works from a prompt alone or a starting image. To try video takes cheaply, set draft: true (a 480p Seedance 2.5 draft), then upgrade_draft the one the user picks to 1080p. If a provider refuses the content, retry once on wan-3-0-video (video) or seedream-5 (images), the least-restricted models. For a multi-shot film or a music video synced to a song use pixeldojo_film; to change, move or extend an existing clip use pixeldojo_video. These are the models the PixelDojo studios use; name another only when the user asks for it. References: `image_url`/`image_urls` for stills, `video_url` for a source clip, `image_path`/`image_paths` for absolute local files (uploaded to 24h temp storage first). A clip or an audio track URL with no `model` runs on seedance-2-reference; a named model that cannot read a clip is swapped for it and the result says so, while a named model with no audio input drops the track. Model-specific settings go in `params` alongside an explicit `model`. Returns asset URLs, or a jobId for pixeldojo_status when the job outlasts the 30s wait.",
692
+ hostedDescription: "Generate an image or video from a prompt with any model in the PixelDojo catalog. With no `model`, a prompt runs on seedream-5, which makes still images only. For a video, name seedance-2-5, which works from a prompt alone or a starting image. To try video takes cheaply, set draft: true (a 480p Seedance 2.5 draft), then upgrade_draft the one the user picks to 1080p. If a provider refuses the content, retry once on wan-3-0-video (video) or seedream-5 (images), the least-restricted models. For a multi-shot film or a music video synced to a song use pixeldojo_film; to change, move or extend an existing clip use pixeldojo_video. These are the models the PixelDojo studios use; name another only when the user asks for it. References: `image_url`/`image_urls` for stills and `video_url` for a source clip, all public http(s) URLs. A clip or an audio track URL with no `model` runs on seedance-2-reference; a named model that cannot read a clip is swapped for it and the result says so, while a named model with no audio input drops the track. Model-specific settings go in `params` alongside an explicit `model`. Returns asset URLs, or a jobId for pixeldojo_status when the job outlasts the 30s wait.",
643
693
  inputZod: InputSchema,
644
694
  inputJsonSchema: InputJsonSchema,
645
695
  allowedModels: null,
@@ -921,6 +971,7 @@ var init_character = __esm({
921
971
  ALLOWED = [
922
972
  "seedream-5",
923
973
  "seedream-4",
974
+ "seedream-5-flash",
924
975
  "google-nano-banana",
925
976
  "wan-2.7-image-edit",
926
977
  "qwen-3-pro",
@@ -932,6 +983,7 @@ var init_character = __esm({
932
983
  FALLBACK_REF_KEY = {
933
984
  "seedream-5": "image_urls",
934
985
  "seedream-4": "image_urls",
986
+ "seedream-5-flash": "image_urls",
935
987
  "google-nano-banana": "image_input",
936
988
  "wan-2.7-image-edit": "image_urls",
937
989
  "qwen-3-pro": "image",
@@ -3225,7 +3277,7 @@ function makeRedactedLogger(target = console) {
3225
3277
  }
3226
3278
 
3227
3279
  // src/server.ts
3228
- var PACKAGE_VERSION = "0.16.0" ;
3280
+ var PACKAGE_VERSION = "0.16.2" ;
3229
3281
  var SERVER_INSTRUCTIONS = "PixelDojo generates images, video, audio and short films across 100+ models, billed in credits from the connected PixelDojo account. A job that runs past the 30-second wait returns a jobId to check later; check it rather than submitting again, since every new submission is charged. Generated asset URLs are deleted one hour after they are created, so download anything the user wants to keep. Finished films are the exception and stay in the account library.";
3230
3282
  function buildServer(options) {
3231
3283
  if (!options.apiKey) {