From d206e1674d038f3062cd5efc4f2682a2aa575893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jim=20Liu=20=E5=AE=9D=E7=8E=89?= Date: Sat, 11 Apr 2026 21:02:18 -0500 Subject: [PATCH] fix(baoyu-article-illustrator): omit model field from batch tasks when unspecified When --model is not provided, build-batch no longer writes a model field into batch task entries; baoyu-imagine resolves the default from env or EXTEND config instead of inheriting a hardcoded script default. Adds tests covering both the omit-by-default and explicit-override paths. --- .../scripts/build-batch.test.ts | 85 +++++++++++++++++++ .../scripts/build-batch.ts | 13 +-- 2 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 skills/baoyu-article-illustrator/scripts/build-batch.test.ts diff --git a/skills/baoyu-article-illustrator/scripts/build-batch.test.ts b/skills/baoyu-article-illustrator/scripts/build-batch.test.ts new file mode 100644 index 0000000..3efe432 --- /dev/null +++ b/skills/baoyu-article-illustrator/scripts/build-batch.test.ts @@ -0,0 +1,85 @@ +import assert from "node:assert/strict"; +import fs from "node:fs/promises"; +import os from "node:os"; +import path from "node:path"; +import { execFile } from "node:child_process"; +import { promisify } from "node:util"; +import test from "node:test"; + +const execFileAsync = promisify(execFile); +const repoRoot = path.resolve(import.meta.dirname, "..", "..", ".."); +const scriptPath = path.join(repoRoot, "skills", "baoyu-article-illustrator", "scripts", "build-batch.ts"); + +async function makeFixture(): Promise<{ + root: string; + outlinePath: string; + promptsDir: string; + outputPath: string; +}> { + const root = await fs.mkdtemp(path.join(os.tmpdir(), "baoyu-article-illustrator-build-batch-")); + const outlinePath = path.join(root, "outline.md"); + const promptsDir = path.join(root, "prompts"); + const outputPath = path.join(root, "batch.json"); + + await fs.mkdir(promptsDir, { recursive: true }); + await fs.writeFile( + outlinePath, + `## Illustration 1 +**Position**: demo +**Purpose**: demo +**Visual Content**: demo +**Filename**: 01-demo.png +`, + ); + await fs.writeFile(path.join(promptsDir, "01-demo.md"), "A demo prompt\n"); + + return { root, outlinePath, promptsDir, outputPath }; +} + +async function runBuildBatch(args: string[]): Promise { + await execFileAsync(process.execPath, ["--import", "tsx", scriptPath, ...args], { + cwd: repoRoot, + }); +} + +test("build-batch omits default model so baoyu-imagine can resolve env or EXTEND defaults", async () => { + const fixture = await makeFixture(); + + await runBuildBatch([ + "--outline", + fixture.outlinePath, + "--prompts", + fixture.promptsDir, + "--output", + fixture.outputPath, + ]); + + const batch = JSON.parse(await fs.readFile(fixture.outputPath, "utf8")) as { + tasks: Array>; + }; + + assert.equal(batch.tasks.length, 1); + assert.equal(batch.tasks[0]?.provider, "replicate"); + assert.equal(Object.hasOwn(batch.tasks[0]!, "model"), false); +}); + +test("build-batch preserves explicit model overrides", async () => { + const fixture = await makeFixture(); + + await runBuildBatch([ + "--outline", + fixture.outlinePath, + "--prompts", + fixture.promptsDir, + "--output", + fixture.outputPath, + "--model", + "acme/custom-model", + ]); + + const batch = JSON.parse(await fs.readFile(fixture.outputPath, "utf8")) as { + tasks: Array>; + }; + + assert.equal(batch.tasks[0]?.model, "acme/custom-model"); +}); diff --git a/skills/baoyu-article-illustrator/scripts/build-batch.ts b/skills/baoyu-article-illustrator/scripts/build-batch.ts index 5f53c12..67dae20 100644 --- a/skills/baoyu-article-illustrator/scripts/build-batch.ts +++ b/skills/baoyu-article-illustrator/scripts/build-batch.ts @@ -8,7 +8,7 @@ type CliArgs = { outputPath: string | null; imagesDir: string | null; provider: string; - model: string; + model: string | null; aspectRatio: string; quality: string; jobs: number | null; @@ -30,7 +30,7 @@ Options: --output Path to output batch.json --images-dir Directory for generated images --provider Provider for baoyu-imagine batch tasks (default: replicate) - --model Model for baoyu-imagine batch tasks (default: google/nano-banana-pro) + --model Explicit model for baoyu-imagine batch tasks (default: resolved by baoyu-imagine config/env) --ar Aspect ratio for all tasks (default: 16:9) --quality Quality for all tasks (default: 2k) --jobs Recommended worker count metadata (optional) @@ -44,7 +44,7 @@ function parseArgs(argv: string[]): CliArgs { outputPath: null, imagesDir: null, provider: "replicate", - model: "google/nano-banana-pro", + model: null, aspectRatio: "16:9", quality: "2k", jobs: null, @@ -132,15 +132,16 @@ async function main(): Promise { } const imageDir = args.imagesDir ?? path.dirname(args.outputPath); - tasks.push({ + const task: Record = { id: `illustration-${String(entry.index).padStart(2, "0")}`, promptFiles: [promptFile], image: path.join(imageDir, entry.filename), provider: args.provider, - model: args.model, ar: args.aspectRatio, quality: args.quality, - }); + }; + if (args.model) task.model = args.model; + tasks.push(task); } const output: Record = { tasks };