Tools
Codex Image Gen
OpenClaw plugin for Codex CLI image generation ($imagegen)
Configuration Example
{
"tool": "codex_image_generate",
"input": {
"prompt": "A futuristic city skyline at sunset, cyberpunk style",
"aspect_ratio": "landscape",
"quality": "high",
"background": "opaque"
}
}
README
# openclaw-codex-image-gen
OpenClaw plugin for generating images via [OpenAI Codex CLI](https://github.com/openai/codex) Responses API (`image_generation` tool).
Inspired by [hermes-gpt-image-gen](https://github.com/Jinbro98/hermes-gpt-image-gen) and [codex-image-generation-skill](https://github.com/Gyu-bot/codex-image-generation-skill).
## Examples
| Prompt | Result |
|--------|--------|
| "A cute robot cat sitting on a cloud, digital art, vibrant colors" | <img src="examples/robot_cat.png" width="300"> |
| Korean e-commerce poster (see below) | <img src="examples/summer_collection.png" width="200"> |
<details>
<summary>Full Korean prompt for the poster</summary>
```
์ ์ํ ์ปฌ๋ ์
๋ฐ์นญ ํฌ์คํฐ, 3:4 ์ธ๋กํ. ์๋จ์ "NEW COLLECTION" ํ
์คํธ,
์ ๋ชฉ "2025 Summer Edition". ์ปฌ๋ ์
์๊ฐ: ์ฌ๋ฆ ํ์ ๋ธ๋ ๋ ์๋ - ์ํธ๋ฌ์ค ํฅ,
๊น๋ํ ์ ํํฐํ
์ด์คํธ, ์์ด์ค ์ถ์ถ ์ต์ ํ. ์ํ ๋ผ์ธ์
: ์ธ๋จธ ๋ธ๋ ๋ ์๋,
์ฝ๋๋ธ๋ฃจ ์์ก, ๋ ๋ชฌ ์๋ฝ ์ ์ ํ. ํ๋จ์ "7์ 15์ผ ์ถ์ | ์ผ๋ฆฌ๋ฒ๋ 20% ํ ์ธ".
ํ๋ฆฌ๋ฏธ์ e-์ปค๋จธ์ค ๋์์ธ, ์ฌ๋ฆ ์ปฌ๋ฌ ํ๋ ํธ.
```
</details>
## How It Works
```
User prompt --> JSON payload --> codex responses (stdin) --> JSONL stream --> base64 decode --> PNG file
```
Calls `codex responses` with a Responses API payload that **forces** the `image_generation` tool via `tool_choice`. The streamed JSONL response is parsed to extract the base64-encoded PNG. Uses your Codex CLI auth session (ChatGPT/OAuth), so image generation uses subscription credits rather than API billing.
## Prerequisites
1. [OpenAI Codex CLI](https://github.com/openai/codex) installed
2. Logged in: `codex login` (ChatGPT/OAuth recommended)
3. Verify: `codex login status` should show "Logged in"
## Installation
```bash
git clone https://github.com/jkf87/openclaw-codex-image-gen.git
cp -r openclaw-codex-image-gen ~/.openclaw/workspace-<your-bot>/local-plugins/codex-image-gen
```
Or download directly:
```bash
mkdir -p ~/.openclaw/workspace-<your-bot>/local-plugins/codex-image-gen
cd ~/.openclaw/workspace-<your-bot>/local-plugins/codex-image-gen
curl -sLO https://raw.githubusercontent.com/jkf87/openclaw-codex-image-gen/main/index.ts
curl -sLO https://raw.githubusercontent.com/jkf87/openclaw-codex-image-gen/main/openclaw.plugin.json
curl -sLO https://raw.githubusercontent.com/jkf87/openclaw-codex-image-gen/main/package.json
```
## Usage in OpenClaw
Once installed, the plugin registers the `codex_image_generate` tool automatically.
### Natural Language (Korean auto-routing)
Just ask naturally -- the `pre_llm_call` hook detects image requests:
```
"๊ณ ์์ด ์ผ๋ฌ์คํธ ๊ทธ๋ ค์ค" --> auto-detect --> codex_image_generate --> PNG saved
```
### Direct Tool Call
```json
{
"tool": "codex_image_generate",
"input": {
"prompt": "A futuristic city skyline at sunset, cyberpunk style",
"aspect_ratio": "landscape",
"quality": "high",
"background": "opaque"
}
}
```
### Tool Parameters
| Parameter | Required | Default | Description |
|-----------|----------|---------|-------------|
| `prompt` | Yes | -- | Creative description of the image |
| `aspect_ratio` | No | `square` | `landscape` (1536x1024) / `square` (1024x1024) / `portrait` (1024x1536) |
| `file_name` | No | auto | Output filename (sanitized, .png) |
| `output_dir` | No | temp | Directory to save the image |
| `background` | No | `auto` | `auto` / `transparent` / `opaque` |
| `quality` | No | `high` | `auto` / `low` / `medium` / `high` |
| `timeout_seconds` | No | `120` | Max wait time in seconds |
### Tool Response
```json
{
"image_path": "/tmp/openclaw-codex-imagegen-abc123/robot_cat.png",
"file_name": "robot_cat.png",
"output_dir": "/tmp/openclaw-codex-imagegen-abc123",
"size_bytes": 1465634,
"assistant_hint": "Image generated at: /tmp/..."
}
```
### Standalone Test (without OpenClaw)
```bash
node -e "
const { spawn } = require('child_process');
const fs = require('fs');
const payload = JSON.stringify({
model: 'gpt-5.4',
instructions: 'Use the image_generation tool to create the requested image.',
input: [{ role: 'user', content: [{ type: 'input_text', text: 'A cute robot cat on a cloud' }] }],
tools: [{ type: 'image_generation', size: '1024x1024', quality: 'high', background: 'auto', action: 'generate' }],
tool_choice: { type: 'image_generation' },
store: false, stream: true,
});
const proc = spawn('codex', ['responses'], { stdio: ['pipe', 'pipe', 'pipe'] });
let out = '';
proc.stdout.on('data', d => out += d);
proc.on('close', () => {
for (const line of out.split('\n')) {
try {
const ev = JSON.parse(line);
if (ev.type === 'response.output_item.done' && ev.item?.type === 'image_generation_call') {
fs.writeFileSync('output.png', Buffer.from(ev.item.result, 'base64'));
console.log('Saved output.png');
}
} catch {}
}
});
proc.stdin.write(payload);
proc.stdin.end();
"
```
## Configuration
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `outputDir` | string | `""` (temp) | Default output directory |
| `timeoutSeconds` | number | `120` | Max wait for codex responses |
| `tempDirMaxAgeHours` | number | `24` | Auto-cleanup threshold for temp dirs |
| `cleanupIntervalMinutes` | number | `60` | Cleanup check interval |
## Korean Trigger Routing
The `pre_llm_call` hook auto-detects image generation requests:
| Category | Keywords |
|----------|----------|
| Engine | codex, ์ฝ๋ฑ์ค, gpt, openai |
| Nouns | ์ด๋ฏธ์ง, ๊ทธ๋ฆผ, ์ฌ์ง, ์์ด์ฝ, ์ผ๋ฌ์คํธ, ๋ฐฐ๊ฒฝ, ๋ก๊ณ , image, picture, icon |
| Verbs | ์์ฑ, ๋ง๋ค, ๊ทธ๋ ค, ๊ทธ๋ฆฌ, ์ ์, generate, create, draw, make |
Triggers when: (engine + noun) OR (noun + verb) detected.
## License
MIT
---
# openclaw-codex-image-gen (ํ๊ตญ์ด)
[OpenAI Codex CLI](https://github.com/openai/codex)์ Responses API๋ฅผ ์ด์ฉํ์ฌ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ๋ OpenClaw ํ๋ฌ๊ทธ์ธ์
๋๋ค.
[hermes-gpt-image-gen](https://github.com/Jinbro98/hermes-gpt-image-gen) ๋ฐ [codex-image-generation-skill](https://github.com/Gyu-bot/codex-image-generation-skill)์ ์ฐธ๊ณ ํ์ฌ ๋ง๋ค์์ต๋๋ค.
## ์์ฑ ์์
| ํ๋กฌํํธ | ๊ฒฐ๊ณผ |
|---------|------|
| "A cute robot cat sitting on a cloud, digital art, vibrant colors" | <img src="examples/robot_cat.png" width="300"> |
| ์ปคํผ ์ ์ํ ์ปฌ๋ ์
ํฌ์คํฐ (์ธ๋กํ) | <img src="examples/summer_collection.png" width="200"> |
## ์๋ ์๋ฆฌ
```
์ฌ์ฉ์ ํ๋กฌํํธ --> JSON ํ์ด๋ก๋ --> codex responses (stdin) --> JSONL ์คํธ๋ฆผ --> base64 ๋์ฝ๋ฉ --> PNG ํ์ผ
```
`codex responses` ๋ช
๋ น์ `tool_choice: { type: "image_generation" }`์ ์ง์ ํ JSON์ stdin์ผ๋ก ๋ณด๋
๋๋ค. Codex CLI์ ์ธ์ฆ ์ธ์
(ChatGPT/OAuth)์ ์ฌ์ฉํ๋ฏ๋ก, ๊ตฌ๋
ํฌ๋ ๋ง์ผ๋ก ์ด๋ฏธ์ง๊ฐ ์์ฑ๋ฉ๋๋ค (๋ณ๋ API ๊ณผ๊ธ ์์).
## ์ฌ์ ์๊ตฌ์ฌํญ
1. [OpenAI Codex CLI](https://github.com/openai/codex) ์ค์น
2. ๋ก๊ทธ์ธ: `codex login` (ChatGPT/OAuth ๊ถ์ฅ)
3. ํ์ธ: `codex login status` -> "Logged in" ํ์
## ์ค์น
```bash
git clone https://github.com/jkf87/openclaw-codex-image-gen.git
cp -r openclaw-codex-image-gen ~/.openclaw/workspace-<๋ด์ด๋ฆ>/local-plugins/codex-image-gen
```
๋๋ ์ง์ ๋ค์ด๋ก๋:
```bash
mkdir -p ~/.openclaw/workspace-<๋ด์ด๋ฆ>/local-plugins/codex-image-gen
cd ~/.openclaw/workspace-<๋ด์ด๋ฆ>/local-plugins/codex-image-gen
curl -sLO https://raw.githubusercontent.com/jkf87/openclaw-codex-image-gen/main/index.ts
curl -sLO https://raw.githubusercontent.com/jkf87/openclaw-codex-image-gen/main/openclaw.plugin.json
curl -sLO https://raw.githubusercontent.com/jkf87/openclaw-codex-image-gen/main/package.json
```
## OpenClaw์์ ์ฌ์ฉ๋ฒ
์ค์นํ๋ฉด `codex_image_generate` ๋๊ตฌ๊ฐ ์๋์ผ๋ก ๋ฑ๋ก๋ฉ๋๋ค.
### ์์ฐ์ด๋ก ์์ฒญ (ํ๊ตญ์ด ์๋ ๋ผ์ฐํ
)
๊ทธ๋ฅ ์์ฐ์ค๋ฝ๊ฒ ๋งํ๋ฉด ๋ฉ๋๋ค:
```
"๊ณ ์์ด ์ผ๋ฌ์คํธ ๊ทธ๋ ค์ค" --> ์๋ ๊ฐ์ง & ์ด๋ฏธ์ง ์์ฑ
"๋ก๊ณ ์ด๋ฏธ์ง ๋ง๋ค์ด์ค" --> ์๋ ๊ฐ์ง & ์ด๋ฏธ์ง ์์ฑ
"codex๋ก ๋ฐฐ๊ฒฝ ์ฌ์ง ์์ฑํด์ค" --> ์๋ ๊ฐ์ง & ์ด๋ฏธ์ง ์์ฑ
```
`pre_llm_call` ํ
์ด ํค์๋ ์กฐํฉ์ ๊ฐ์งํ์ฌ `codex_image_generate` ๋๊ตฌ๋ก ์๋ ๋ผ์ฐํ
ํฉ๋๋ค.
### ๋๊ตฌ ํ๋ผ๋ฏธํฐ
| ํ๋ผ๋ฏธํฐ | ํ์ | ๊ธฐ๋ณธ๊ฐ | ์ค๋ช
|
|---------|------|--------|------|
| `prompt` | O | -- | ์ด๋ฏธ์ง ์ค๋ช
(ํ๊ธ/์์ด ๋ชจ๋ ๊ฐ๋ฅ) |
| `aspect_ratio` | X | `square` | `landscape` (1536x1024) / `square` (1024x1024) / `portrait` (1024x1536) |
| `file_name` | X | ์๋ | ์ถ๋ ฅ ํ์ผ๋ช
(.png) |
| `output_dir` | X | ์์ | ์ ์ฅ ๋๋ ํฐ๋ฆฌ |
| `background` | X | `auto` | `auto` / `transparent` / `opaque` |
| `quality` | X | `high` | `auto` / `low` / `medium` / `high` |
| `timeout_seconds` | X | `120` | ์ต๋ ๋๊ธฐ ์๊ฐ (์ด) |
### ์๋ต ์์
```json
{
"image_path": "/tmp/openclaw-codex-imagegen-abc123/summer_collection.png",
"file_name": "summer_collection.png",
"output_dir": "/tmp/openclaw-codex-imagegen-abc123",
"size_bytes": 2011115,
"assistant_hint": "Image generated at: /tmp/..."
}
```
### OpenClaw ์์ด ๋จ๋
ํ
์คํธ
```bash
node -e "
const { spawn } = require('child_process');
const fs = require('fs');
const payload = JSON.stringify({
model: 'gpt-5.4',
instructions: 'Use the image_generation tool to create the requested image.',
input: [{ role: 'user', content: [{ type: 'input_text', text: '๊ท์ฌ์ด ๋ก๋ด ๊ณ ์์ด๊ฐ ๊ตฌ๋ฆ ์์ ์์์๋ ๊ทธ๋ฆผ' }] }],
tools: [{ type: 'image_generation', size: '1024x1024', quality: 'high', background: 'auto', action: 'generate' }],
tool_choice: { type: 'image_generation' },
store: false, stream: true,
});
const proc = spawn('codex', ['responses'], { stdio: ['pipe', 'pipe', 'pipe'] });
let out = '';
proc.stdout.on('data', d => out += d);
proc.on('close', () => {
for (const line of out.split('\n')) {
try {
const ev = JSON.parse(line);
if (ev.type === 'response.output_item.done' && ev.item?.type === 'image_generation_call') {
fs.writeFileSync('output.png', Buffer.from(ev.item.result, 'base64'));
console.log('Saved output.png');
}
} catch {}
}
});
proc.stdin.write(payload);
proc.stdin.end();
"
```
## ์ค์
| ํค | ํ์
| ๊ธฐ๋ณธ๊ฐ | ์ค๋ช
|
|----|------|--------|------|
| `outputDir` | string | `""` (์์) | ๊ธฐ๋ณธ ์ถ๋ ฅ ๋๋ ํฐ๋ฆฌ |
| `timeoutSeconds` | number | `120` | codex responses ์ต๋ ๋๊ธฐ ์๊ฐ |
| `tempDirMaxAgeHours` | number | `24` | ์์ ๋๋ ํฐ๋ฆฌ ์๋ ์ ๋ฆฌ ๊ธฐ์ค (์๊ฐ) |
| `cleanupIntervalMinutes` | number | `60` | ์ ๋ฆฌ ์ฒดํฌ ์ฃผ๊ธฐ (๋ถ) |
## ํ๊ตญ์ด ํธ๋ฆฌ๊ฑฐ ๋ผ์ฐํ
`pre_llm_call` ํ
์ด ์๋ ํค์๋ ์กฐํฉ์ ๊ฐ์งํฉ๋๋ค:
| ๋ถ๋ฅ | ํค์๋ |
|------|--------|
| ์์ง | codex, ์ฝ๋ฑ์ค, gpt, openai |
| ๋ช
์ฌ | ์ด๋ฏธ์ง, ๊ทธ๋ฆผ, ์ฌ์ง, ์์ด์ฝ, ์ผ๋ฌ์คํธ, ๋ฐฐ๊ฒฝ, ๋ก๊ณ , image, picture, icon |
| ๋์ฌ | ์์ฑ, ๋ง๋ค, ๊ทธ๋ ค, ๊ทธ๋ฆฌ, ์ ์, generate, create, draw, make |
**๊ฐ์ง ์กฐ๊ฑด**: (์์ง + ๋ช
์ฌ) ๋๋ (๋ช
์ฌ + ๋์ฌ) ์กฐํฉ -> ์๋ ๋ผ์ฐํ
## ๋ผ์ด์ ์ค
MIT
tools
Comments
Sign in to leave a comment