# GPT-Image-2 稳定生图工具

项目无关的 `gpt-image-2` 稳定生图工具，封装多条中转通道（优先走 OpenAI Images API），自动健康度排序、故障转移、响应解析。

## 安装

```text
pip install requests Pillow
```

## 最小使用

工作目录放一个 `.env`，包含一个或多个通道：

```text
GPT_IMAGE_2_CHANNEL_1_KEY=sk-你的key
GPT_IMAGE_2_CHANNEL_1_URL=https://your-api-gateway-1.com
GPT_IMAGE_2_CHANNEL_2_KEY=sk-你的key
GPT_IMAGE_2_CHANNEL_2_URL=https://your-api-gateway-2.com
```

```python
from tool_image import generate_image, inpaint_image, ensure_composite_ref

# 1. 文本生图
res = generate_image(
    prompt="A small dark blue energy cocoon floating above snowy ruins, cinematic 16:9.",
    output_path=Path("out/cocoon"),
)

# 2. 带参考图生图（先合并多张锚点为单张 JPEG，避免多 base64 触发空响应）
composite = ensure_composite_ref("hero_ref", [
    Path("anchors/scene.png"),
    Path("anchors/character.png"),
])
res = generate_image(
    prompt="...",
    output_path=Path("out/hero"),
    reference_path=composite,
)

# 3. 局部重绘
res = inpaint_image(
    source_path=Path("out/hero.png"),
    output_path=Path("out/hero_fixed"),
    rect_xyxy=(470, 430, 600, 540),
    prompt="Same character, eyes closed and sleeping. Keep all else identical.",
)
```

## API 表

| 函数 | 用途 |
|---|---|
| `generate_image(prompt, output_path, reference_path=None, ...)` | 主入口；返回 `GenResult` |
| `inpaint_image(source_path, output_path, rect_xyxy, prompt, ...)` | 局部重绘；返回 `InpaintResult` |
| `ensure_composite_ref(name, sources, ...)` | 合并多张参考图为单张 JPEG |
| `load_channels()` | 返回 `Channel[]` |
| `probe_channels()` | CLI 用：打印通道 + 健康度 |

## 局部重绘的两条策略

| 策略 | 实现 | 适用 |
|---|---|---|
| `native` | `/v1/images/edits` + alpha mask | 不含未成年人的源图 |
| `engineered` | crop → 单参考生图 → feather paste | 通用，含未成年人源图必须用 |
| `auto`（默认）| 先试 native，失败 fallback engineered | 通用 |

## 设计原则（验证过的坑）

1. **多 base64 参考图必触发空响应**：永远用 `ensure_composite_ref` 合成单张
2. **chat 风格响应前导可能是 keepalive**：解析器跳过前导
3. **4xx schema 错不重试同通道**：直接跳到下一通道
4. **5xx / ChunkedEncodingError / 空响应可重试**：默认每通道 2 次
5. **健康度按 success/(success+failure) 软排序**：自动给稳定的通道更多机会
