Studio image batches
Creators can ask for portraits for their existing characters or a freeform set such as “Generate ten girls with different hair colors.” Studio prepares one independently described image per item, up to 30 items per batch. The inline card lets the creator select items, edit prompts and choose the model before confirming the estimated cost once.
Confirmation ends the assistant run and creates a persistent queue. Generating, delivering, binding, retrying and resuming the images do not call the assistant model. Image generation still costs credits per image at actual usage; the estimate is not a spending cap. Preparation can involve multiple assistant turns when the world needs to be inspected or a custom UI needs to be connected first.
Delivery and recovery
- Items without a target are saved to the creator's asset library (and the world's bound folder when present).
entry_portraitassigns an existing Lorebook entry's portrait.component_imageupdates a key in_generated/character-images.tsx, which the assistant must first import into the mounted custom UI. The binding layer verifies the connection and never executes component code.- Existing images are skipped. If the author changes a target while generation is running, assignment stops and the generated asset remains in the library. Binding retries reuse that asset.
- Only two generation jobs per user are active at once, including jobs submitted outside Studio batches. Paused delivery receipts do not occupy global provider execution slots.
- Each admitted item reserves estimated credits. All wallet spenders must respect reservations. Actual cost exceeding available balance pauses delivery; the uploaded output is retained and can be settled after funding without a second generation request.
- Refresh or another worker process can resume from database state. A paid provider request with an unknown outcome is not automatically replayed. Failed items require an explicit retry.
- Confirmation is idempotent by user/run/tool call. Retry requests carry a persistent request ID, including when an earlier retry has already failed again.
- Published-world assignments go through the existing pending-edit/review path. Concurrent local text edits preserve a new server portrait; a portrait the author explicitly changed keeps the author's value.
Activation
- The existing deployment preparation runs
packages/server/scripts/add-image-batches.sqlbefore switching traffic. For a manual rollout, apply it before starting the dispatcher. It createsimage_batches,image_batch_itemsandimage_batch_retry_requestsand is safe to apply again. The existing Studio credit reservation schema must already be present. - Enable
STUDIO_CREDIT_RESERVATIONS_ENABLED=trueon all processes that spend wallet credits, or use the existingSTUDIO_CREDIT_RECOVERY_ENABLED=truerollout. Keep reservation protection enabled while outstanding holds exist. - Use the existing Smart image provider configuration (
OPENROUTER_IMAGE_API_KEY, storage and provider budgets). In embedded mode the website process starts the batch dispatcher; in external mode the image worker starts it.
Without reservation protection, Studio does not advertise the batch tool and new batches are rejected. No production migration, paid provider request or deployment is part of local validation.
Validation
The isolated server runner blocks external provider requests and uses in-memory PostgreSQL-compatible storage. Coverage includes the real Studio SSE/confirmation/status handlers, ten distinct prompts, wallet holds against competing spenders, duplicate approvals and delayed retry replays, failed-only retries, retained output settlement, process recovery, provider budget renewal, ownership checks and target conflicts. Frontend tests exercise the rendered confirmation card, polling recovery, account/conversation switching and the real Studio callbacks. Engine tests cover portrait merge and published-world material changes.
Run from the repository root:
node packages/server/scripts/test-local.mjs src/routes/agent-image-batch.test.ts src/lib/studio-tools/image-batch-proposal.test.ts src/lib/generation/image-batches.test.ts src/lib/generation/image-batch-bindings.test.ts src/lib/studio-conversations.test.ts
corepack pnpm typecheck
corepack pnpm build