Skip to content

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_portrait assigns an existing Lorebook entry's portrait. component_image updates 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

  1. The existing deployment preparation runs packages/server/scripts/add-image-batches.sql before switching traffic. For a manual rollout, apply it before starting the dispatcher. It creates image_batches, image_batch_items and image_batch_retry_requests and is safe to apply again. The existing Studio credit reservation schema must already be present.
  2. Enable STUDIO_CREDIT_RESERVATIONS_ENABLED=true on all processes that spend wallet credits, or use the existing STUDIO_CREDIT_RECOVERY_ENABLED=true rollout. Keep reservation protection enabled while outstanding holds exist.
  3. 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:

sh
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