keryx cover¶
Generate cover art via the image provider (Gemini/Imagen) — a port of the blog
gen-cover.py. Resolves an article theme for the style prefix + aspect and
appends the per-post --scene.
keryx cover --scene "a quiet desk at dawn" [--theme <article-kw>] [--model <id>] [--n N] [--out cover]
keryx cover --prompt "a fully-formed prompt …" # bypass theme style + scene
| Flag | Meaning | Default |
|---|---|---|
--scene |
the per-post scene (required unless --prompt) |
— |
--prompt |
a fully-formed prompt used verbatim (bypasses theme style + scene) | — |
--theme |
article theme (style prefix + aspect) | configured article default |
--model |
force a specific image model id | config providers.gemini.model, else the fallback chain |
--n |
number of candidate samples | 1 |
--out |
output path prefix → <out>-<i>.png |
cover |
--dry-run |
estimate what this would cost and generate nothing | false |
Credential: GEMINI_API_KEY (env). Image generation is non-deterministic — make
several samples and pick a clean one. Add --output json for the list of paths.
When you get fewer samples than you asked for¶
The image providers filter candidates non-deterministically, so a request for --n
3 can come back with two. keryx asks the provider again for the shortfall, up to
three extra attempts, and writes the full batch when they arrive.
If even that cannot reach the count, the run warns and still writes what it got, naming both numbers:
The exit status stays 0 — a partial batch is still usable, and you were going to
look at every sample anyway. The warning exists because the alternative is
choosing from a sample of one while believing you asked for two, which quietly
removes the fallback the "generate several, pick a clean one" workflow depends on.
Scripting a batch? Count the paths in --output json rather than trusting the
exit code.
Costing a run before making it¶
--dry-run prices the run and generates nothing — no provider call, no files, no
spend. It needs no API key, so it also works as a way to check what a command
would do before you configure credentials.
dry run: would generate 4 cover take(s)
est. spend: ~USD 0.12
best-effort estimate, and an upper bound — an unchanged request is served from the cache without spending.
nothing was generated and nothing was written.
The estimate is an upper bound on the images you asked for: an unchanged request
is served from the content cache without spending (R-GLOBAL-9), so a real run may
cost nothing. The one case that can exceed it is a topped-up short batch — if the
provider returns fewer samples than --n, keryx asks again for the shortfall, and
a provider that bills per requested sample rather than per returned image would
charge for those extra attempts. You never receive more images than --n. Rates come
from providers.image.price_per_image and friends — round, tunable cues rather than
a vendor's billed rate. When the estimate crosses spend.confirm_above.*, the dry
run says so. --output json gives the same figures structured, which is how an
assistant driving keryx over MCP asks what something costs before committing.
keryx cover --scene "an over-engineered toaster, one idea" --theme editorial --n 4
# writes cover-1.png … cover-4.png
Provider-selected via providers.image (default Gemini) — see
Providers. Tries the Imagen models, falling back
to the Gemini image models (parity with the script). R-GEN-1..3.