diff --git a/bin/icon.ts b/bin/icon.ts index 1fa8cda..0bed686 100755 --- a/bin/icon.ts +++ b/bin/icon.ts @@ -47,7 +47,7 @@ const USAGE = `Usage: icon style <${Object.keys(STYLES).join('|')}|agentic|all> [DRAW OPTIONS] DRAW OPTIONS: [--out DIR] [--only mail,…] [--no-draw] [--draw-only] [--force] - [--concurrency N] [--quality low|medium|high] + [--concurrency N] [--quality low|medium|high] [--model M] [--style-dir DIR] [--dry-run] A colour style draws every UI icon with an image model (needs OPENAI_API_KEY), @@ -133,7 +133,7 @@ if (isMain(import.meta.url)) { try { const { flags, values, positional } = parseArgs(process.argv.slice(2), { boolean: ['--json', '--help', '--no-draw', '--draw-only', '--force', '--dry-run'], - string: ['-o', '--out', '--sizes', '--color', '--only', '--category', '--mode', '--concurrency', '--quality', '--style-dir'], + string: ['-o', '--out', '--sizes', '--color', '--only', '--category', '--mode', '--concurrency', '--quality', '--style-dir', '--model'], }); const [verb, ...rest] = positional; if (flags.has('--help') || !verb) { @@ -275,6 +275,7 @@ if (isMain(import.meta.url)) { styleDir: values.get('--style-dir') ?? join(process.env['HOME'] ?? '', 'brand-assets', 'openemoji', 'master'), concurrency: Number(values.get('--concurrency') ?? HQ_CONCURRENCY), quality, + ...(values.get('--model') ? { model: values.get('--model')! } : {}), force: flags.has('--force'), log: (line) => process.stderr.write(`${line}\n`), render: (svg, size) => Buffer.from(new Resvg(svg, { fitTo: { mode: 'width', value: size } }).render().asPng()), diff --git a/src/icon-hq.ts b/src/icon-hq.ts index 8cc808e..e4e0e21 100644 --- a/src/icon-hq.ts +++ b/src/icon-hq.ts @@ -118,6 +118,12 @@ export interface HqDrawOptions { styleDir: string; concurrency: number; quality: string; + /** + * The image model; HQ_MODEL when absent. gpt-image-2 now answers + * "Transparent background is not supported for this model", so a top-up + * drawing (a new icon after the set shipped) needs one that still does. + */ + model?: string; force: boolean; log: (line: string) => void; render: (svg: string, size: number) => Promise | Buffer; @@ -202,7 +208,7 @@ export async function drawHq(options: HqDrawOptions): Promise { try { report.calls += 1; const result = await options.caller({ - model: HQ_MODEL, + model: options.model ?? HQ_MODEL, // A brand takes no style reference: the mark is the only thing the // model should be looking at, and an emoji master beside it is an // invitation to redraw. @@ -213,7 +219,7 @@ export async function drawHq(options: HqDrawOptions): Promise { await writeFile(join(master, `${key}.png`), result.png); await writeFile( join(options.out, style.dir, 'prompts.jsonl'), - `${JSON.stringify({ key, style: style.id, prompt, brand: Boolean(brand), references: brand ? ['mark'] : ['line', ...style.emojiRefs] })}\n`, + `${JSON.stringify({ key, style: style.id, model: options.model ?? HQ_MODEL, prompt, brand: Boolean(brand), references: brand ? ['mark'] : ['line', ...style.emojiRefs] })}\n`, { flag: 'a' }, ); report.drawn.push(key);