feat: add codex-imagegen backend for non-Codex runtimes

Implements the preferred_image_backend: codex-imagegen config key
already referenced in several SKILL.md files but with no corresponding
backend. Bridges non-Codex runtimes (Claude Code, etc.) to Codex CLI's
built-in image_gen tool via 'codex exec'. Uses the user's Codex
subscription — no OPENAI_API_KEY required.

Reliability:
- Retry with exponential backoff (default 2 retries, configurable)
- 9 classified error kinds (retryable vs non-retryable)
- Node child_process timeout with SIGTERM→SIGKILL ladder

Correctness:
- Verifies image_gen was actually invoked (not bypassed) by checking
  $CODEX_HOME/generated_images/{thread_id}/ for a PNG
- PNG magic byte validation
- Output file size sanity check

Observability:
- Structured JSONL logging with --log-file
- Verbose stderr mode with --verbose
- Returns thread_id, tool_calls, token usage in result JSON
- Raw codex event stream preserved per attempt for debugging

Efficiency:
- Idempotency cache via --cache-dir (sha256 of prompt+aspect+refs)
- Cache hit returns in <0.3s vs 50-90s cold

Features:
- --ref reference images (repeatable, passed through to codex exec --image)
- --retries, --retry-delay, --timeout all configurable
- File lock serializes concurrent invocations

Testing:
- 16 Bun unit tests across parser, cache, validator
- Path-filtered CI workflow at .github/workflows/codex-imagegen-tests.yml
- Composes with existing test.yml without conflicts

Architecture:
- scripts/codex-imagegen.sh: thin bash entrypoint (bun → npx -y bun fallback)
- scripts/codex-imagegen/: TypeScript module
  - main.ts (orchestrator), types.ts (CliOptions/GenerateResult/GenError),
    spawn.ts (child_process), parser.ts (JSONL events), validator.ts
    (image_gen check + PNG magic), cache.ts (sha256 cache + FileLock),
    logger.ts (JSONL structured logger)

Trade-offs documented in docs/codex-imagegen-backend.md:
- 5-10x slower than direct OpenAI API (or near-free on cache hit)
- ToS gray area: image_gen is documented for interactive use; non-
  interactive invocation via codex exec is not explicitly addressed.
  Suitable for personal low-volume use; users are responsible for
  ensuring their usage complies with applicable terms of service.
This commit is contained in:
Yelban
2026-05-20 00:50:24 +08:00
parent 5d2a39c636
commit e98fa33bc2
14 changed files with 1253 additions and 0 deletions
+16
View File
@@ -66,6 +66,22 @@ Skills that prompt users for choices MUST declare the tool-selection convention
Skills that render images MUST declare the backend-selection convention **inline** in exactly one place per `SKILL.md` — a `## Image Generation Tools` section near the top (after `## User Input Tools`). Do NOT link out to [docs/image-generation-tools.md](docs/image-generation-tools.md); that doc is the author-side canonical source — copy its body into each SKILL.md. Concrete tool names (`imagegen`, `image_generate`, `baoyu-imagine`) elsewhere in a skill are treated as examples — other runtimes substitute their local equivalent under the rule. The rule is stateless: use whatever backend is available; if multiple, ask the user once; if none, ask how to proceed. Every rendered image's full prompt must be written to a standalone `prompts/NN-*.md` file before any backend is invoked. Backend skills (`baoyu-imagine`, `baoyu-image-gen`, `baoyu-danger-gemini-web`) are exempt — they render directly rather than selecting a backend.
### `codex-imagegen` Backend
A backend for non-Codex runtimes (e.g., Claude Code) that generates images by spawning `codex exec --json --sandbox danger-full-access` and delegating to Codex CLI's built-in `image_gen` tool. Uses the user's Codex subscription — no `OPENAI_API_KEY` required.
Invoke via:
```bash
./scripts/codex-imagegen.sh \
--image <output.png> \
--prompt-file prompts/01-cover.md \
--aspect 16:9 \
--cache-dir ~/.cache/baoyu-codex-imagegen
```
Stdout emits a single JSON line: `{"status":"ok","path":...,"bytes":N,...}`. On failure, `{"status":"error","error_kind":...}`. Skills route here by setting `preferred_image_backend: codex-imagegen` in EXTEND.md. Full reference: [docs/codex-imagegen-backend.md](docs/codex-imagegen-backend.md).
## Deprecated Skills
| Skill | Note |