diff --git a/CHANGELOG.md b/CHANGELOG.md index 46652aa..4a5f441 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ > 所以不是每个版本号都有条目。条目格式 `## <版本> — <日期>`,新条目加在最上面。 > 工程口径的完整记录见 `PROGRESS.md` / git log。 +## 0.60.20 — 2026-07-31 + +- 修复「GPT 生图」因图像模型配置过期而无法生成图片的问题。 + ## 0.60.19 — 2026-07-31 - 修复清空对话时可能出现服务器内部错误、导致对话无法清空的问题。 diff --git a/PROGRESS.md b/PROGRESS.md index dfebca5..54c0da6 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -2,7 +2,7 @@ > 配合 `DESIGN.md`。本文件只记 phase 状态、决策偏差、文件量、下一步。每条 1-2 句:做了啥 + 关键判断;细节查 `git log` / `git diff` / `DESIGN §7.9`。 -最后更新:2026-07-31(修复清空对话 500,bump 0.60.19) +最后更新:2026-07-31(修复 GPT 生图模型路由,bump 0.60.20) --- @@ -23,6 +23,7 @@ ### 2026-07-31 +- **07-31 / 0.60.20 / GPT 生图模型路由修复**:unifyllm 的 Images 端点已由历史文本渠道名切换为专用图像模型,媒体配置同步改用当前 `/v1/models` 开放的 `gpt-image-2`,保持既有 `/images/generations`、prompt-only 工具契约与 `b64_json` 解析不变;手工干跑增加模型 ID 回归断言。真实 OpenAI 格式请求返回 HTTP 200 及完整 base64 图像,相关 16 项 unittest 通过(1 项按环境跳过),diff 格式检查通过;未连接数据库、无 schema、migration 或 API 变化。 - **07-31 / 0.60.19 / 清空对话 500 修复**:清空接口补查后续标题重置逻辑所需的 `title_source`,修复仅查询 `run_status` 后访问缺失字段导致的 `AttributeError` 与事务回滚;原有 DB 路由用例已覆盖自动标题和人工标题两类清空行为,无 schema、migration、API 或数据语义变化。16 项无 DB 路由测试、Python 编译、致命静态检查与 diff 格式检查通过;未设置 `ZCBOT_TEST_DB_URL`,DB 路由测试按安全门控跳过。 - **07-31 / 0.60.18 / 任务列表默认按最近更新时间排序**:普通任务列表的前后端默认排序统一由创建时间倒序改为更新时间倒序,最近继续处理的对话会回到顶部;显式 `ordering=-created_at` 等既有排序参数和全部下拉选项保持兼容。新增默认值、非法参数回退及创建时间兼容 3 项单元测试,Python/JavaScript 语法与 diff 格式检查通过;无 schema、migration 或依赖变化。 - **07-31 / 0.60.17 / 消息 JSONB NUL 字符兼容**:外部工具从论文、PDF 等来源提取的文本可能夹带真实 NUL,Python JSON 会编码为 PostgreSQL `jsonb` 无法转换成 text 的 `\u0000`,导致 tool message INSERT 回滚并中断 run。新增递归清洗并在 `Message.payload` ORM 写入边界统一守门,`Session.append` 同步清洗内存上下文,保留制表符、换行及其余 Unicode;无 schema、migration 或存量数据改动。相关 6 项单元测试、Python 编译及 diff 格式检查通过;未设置 `ZCBOT_TEST_DB_URL`,未连接数据库。 diff --git a/config/media/unifyllm.yaml b/config/media/unifyllm.yaml index 8c95884..ee7535b 100644 --- a/config/media/unifyllm.yaml +++ b/config/media/unifyllm.yaml @@ -3,12 +3,12 @@ # 接入方式:OpenAI Images API /images/generations,tools/gpt_image.py 直调 # (复用 core/ark_client.py 的通用 HTTP 封装)。响应返 b64_json,无需二次下载。 # -# 实测行为(2026-07-10,gpt-5.6-sol 渠道): -# - images 端点按**渠道模型名**路由:model 必须传网关上已开通的名字(gpt-5.6-sol 可, -# gpt-image-1 → 503 model_not_found) -# - size / quality 参数被网关忽略(传 1024x1536 / quality=medium 均不生效),实际尺寸由 -# 上游模型按画面自动决定(实测出过 1254x1254 / 1536x1024),quality 恒 low —— 所以 -# tool 只暴露 prompt,不暴露尺寸/质量(暴露了也不生效,还误导模型) +# 实测行为: +# - 2026-07-10 网关曾要求用 gpt-5.6-sol 渠道名路由;2026-07-31 起 images 端点 +# 严格要求图像模型,当前 /v1/models 开放 gpt-image-2。文本模型 gpt-5.6-sol 会返回 +# HTTP 400 "images endpoint requires an image model"。 +# - 旧 gpt-5.6-sol 渠道曾忽略 size / quality。切换 gpt-image-2 后先保持 tool 的 +# prompt-only 对外契约;尺寸/质量能力需单独验证后再开放,避免未经验证改变现有行为。 # - 不支持改图(i2i 需 /images/edits multipart,v1 不接);改图场景切回豆包 Seedream # - 单张耗时 ~35-40s(慢于 seedream 的 3-5s) # - 价格:网关未公布价目,price 暂 0(usage tokens 记进 units,拿到价目后回填对账) @@ -19,7 +19,7 @@ base_url: https://unifyllm.ai/v1 image: gpt_image: - model_id: gpt-5.6-sol + model_id: gpt-image-2 display_name: GPT 生图 endpoint: /images/generations price_cny_per_image: 0 # 网关价目未知,成本先记 0;拿到价目改这里 + 重启 diff --git a/core/__init__.py b/core/__init__.py index 5fd3536..9e5039b 100644 --- a/core/__init__.py +++ b/core/__init__.py @@ -1,3 +1,3 @@ # zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。 # 改版本只动这一行。 -__version__ = "0.60.19" +__version__ = "0.60.20" diff --git a/scripts/test_gpt_image_manual.py b/scripts/test_gpt_image_manual.py index 5a7da9f..d09de4d 100644 --- a/scripts/test_gpt_image_manual.py +++ b/scripts/test_gpt_image_manual.py @@ -36,6 +36,13 @@ def main() -> int: if gw is None: print("[FAIL] unifyllm.yaml 未装配(UNIFYLLM_API_KEY 缺失?)") return 1 + image_cfg = (gw.raw.get("image") or {}).get("gpt_image") or {} + model_ok = image_cfg.get("model_id") == "gpt-image-2" + print( + f"[{'OK' if model_ok else 'FAIL'}] gpt_image model=" + f"{image_cfg.get('model_id') or 'MISSING'}" + ) + fails += 0 if model_ok else 1 # variant 选择:显式 gpt_image / 显式 seedream_5 / 空 fallback cases = [