the standard library
nika:image_generate
Generate image assets (local compat servers · openai gpt-image-2 · gemini gemini-3.1-flash-image · xai grok-imagine-image · mock for offline runs) — saves files under output_dir and returns paths + dimensions + sha256 (+ a provenance manifest); image bytes never ride outputs. One of 28 builtins in the closed nika: namespace.
the media familyimages, audio, charts: assets, not blobs
- mediafamily4 tools
- 24argsdeclared contract
- 2requiredcheck teaches a miss
- 1skeletonsship this tool
the contract
24 args · 2 requiredA missing required arg is a nika check finding before anything runs; the vocabulary below comes from the binary itself (nika catalog --tools --json), not from prose.
- provider
stringlocal | openai | gemini | xai | mock (inferred from model: when omitted · local is never inferred)- model
stringprovider model id · defaults: stablediffusion (local · LocalAI convention) · gpt-image-2 · gemini-3.1-flash-image · grok-imagine-image · mock-image-1- prompt*
stringthe creative brief the provider renders- mode
stringgenerate (default · text→image) | edit (source image(s) + instruction)- image
stringmode:edit · one source image PATH (read · permit-gated fs.read)- images
stringmode:edit · source image PATHS (multi-ref · capped per provider)- mask
stringmode:edit · optional pixel-mask PATH (openai/local only · refused elsewhere)- n
integervariant count 1..=10 (gemini runs n sequential calls)- aspect_ratio
string1:1 | 16:9 | 9:16 | 4:3 | 3:4 | 3:2 | 2:3 | 21:9- size
stringexact WIDTHxHEIGHT (gpt-image-2 arbitrary /16 sizes · gemini folds to a size class) or auto — an exact size wins over aspect_ratio- quality
stringauto (default) | low | medium | high | ultra (folds to high on openai · model-tier on gemini)- format
stringpng (default) | jpeg | webp — magic bytes are the authority on what lands- compression
integer0..=100 · jpeg/webp only (openai output_compression)- background
stringauto (default) | transparent (needs png/webp and a supporting model) | opaque- seed
integergemini best-effort · openai has no seed (warned + dropped)- reference_images
arraymedia roadmap — rejected loudly in V1- provider_options
objectvetted pass-through · openai {moderation, user} · gemini {thinking_level, image_size} · xai {user, resolution}- output_dir*
stringdirectory the assets land in (rides the declared permits.fs boundary)- filename_prefix
stringfilename stem (else metadata.page_slug, else `image`) — sanitized, traversal-free- save
booleanV1 contract: stays true — assets land on disk, never inline- manifest
booleanwrite the provenance manifest JSON beside the assets (default true)- metadata
objectfree provenance fields (campaign · page_slug · locale …) echoed to output + manifest- timeout_ms
integerper-request deadline · default 180000 · 1000..=600000- debug
booleanecho the sanitized raw provider response (base64 stripped)
in a real file
from the media-asset-pack skeleton render: with: brief_image_prompt: ${{ tasks.brief.output.image_prompt }} invoke: tool: "nika:image_generate" args: provider: mock # SLOT: local | openai | gemini | xai (local/mock first) prompt: "${{ with.brief_image_prompt }}" output_dir: "${{ const.out_dir }}" filename_prefix: "asset" # SLOT: filename stema verbatim excerpt, real line numbers from media-asset-pack.nika.yaml, conformance-gated upstream on every spec push. open the full skeleton →
cross-references
ships in skeletons
the check gates
the media family
4 toolsimages, audio, charts: assets, not blobs.
- nika:chart
- nika:image_fx
- nika:image_generate
- nika:tts_generate
Machines read the same vocabulary at /tools/catalog.json; the contract lives in spec 06 · stdlib. Install and ask the binary itself: nika catalog --tools. Read the spec →