AGPL-3.0-or-later · forever.

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 required

A 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
media-asset-pack.nika.yaml
  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 stem

a 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 tools

images, audio, charts: assets, not blobs.

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 →