gobuild./...govet./...gotest./internal/core/provider/..../admin/...-vgotest./...# 重新编译部署 portal 后,管理端修改 extra_body,再提交一次文生图# SELECT id, api_type, extra_body FROM provider_models WHERE id IN (4,5);# SELECT g.id, g.status, g.provider_attempt_count, o.size_bytes# FROM generations g JOIN generation_outputs o ON o.generation_id = g.id# ORDER BY g.id DESC LIMIT 1;
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
基本信息
依赖与并行
子项目影响
internal/core(provider 校验)、admin(表单校验)、provider_models配置数据go test ./internal/core/provider/... ./admin/...,以及一次真实文生图原始需求
要解决什么
现状
chorus 对
/v1/images/generations不发送任何尺寸参数,输出尺寸完全由上游默认值决定(实测均为 1536×1024),chorus 对此没有控制权。上游若改默认值,chorus 的输出会无声跟着变。cmhub 对同一端点发送
resolution与aspect_ratio(apps/ai/providers/openai_compatible.py:337)。经对照请求验证,该中转站接受resolution/aspect_ratio,不认size——之前"忽略size"的现象是参数名不对,不是上游忽略。首次实施失败:
extra_body白名单拒绝resolution2026-08-26 09:35 把
provider_models.id=4的extra_body设为{"resolution": "1K"}后,generation 18 立即失败:2 毫秒,没有发出任何网络请求。 原因是
internal/core/provider/openai.go:349的白名单不含resolution:parseExtraBody返回ErrInvalidConfig→NewOpenAI失败 → worker 的factoryErr分支 → 终态upstream_unknown。原工单"无需改代码"的判断是错的:当时只看了
mergeExtra的覆盖行为,没看它上游的parseExtraBody校验。白名单按 OpenAI 官方参数命名(size/quality),与该中转站的resolution/aspect_ratio体系对不上。配置已于同日回滚为
{},文生图恢复正常。附带确认
generation 18 的 attempts 记录中
error_code=upstream_unknown、retryable=false、latency_ms=2三者自洽,未被终态码覆盖,证明 #63 的修复在真实运行中生效。做什么 / 不做什么
resolution加入extra_body白名单(核心域与管理端两处),补测试,然后配置provider_models.id=4并验证。aspect_ratio。沿用先前决定:上游默认的 3:2 横构图对现有地图类提示词可能更合适,强制 1:1 有变差风险。将来需要时用同一机制追加。model/messages/n/response_format/authorization必须继续被拒绝,这是白名单存在的理由。provider_models.id=5(其size对 edits 端点正确)。response_format或任何 Go 协议实现。已确认方案
代码改动
白名单在两处重复定义,必须同步修改,否则管理端能存进去、运行时却拒绝(正是本次失败的形态):
internal/core/provider/openai.go:349parseExtraBodyadmin/app/chorus/service.go:1247validateExtraBody两处的
allowed均改为:配置改动
代码上线后,管理端把
provider_models.id=4的extra_body设为:收益边界
唯一确定的收益是拿回尺寸控制权。以下都不是收益:"和 cmhub 一致"本身;提速(未证实,同一提示词的成功样本在 244–465 秒间大幅波动);响应体变小加快传输(已证伪,20 KB/s 是中转站边生成边吐数据,不是带宽限制)。
已知的语义落差
cmhub 中
resolution是每次请求的参数,调用方可按场景变化;chorus 的extra_body是 provider_model 级全局常量,填入后所有文生图请求共用同一值。chorus 目前没有请求级参数通道(provider.Request只有Kind/APIType/ModelID/RenderedPrompt/Inputs,用户端也无尺寸选项)。若将来要让用户自选尺寸,需另立工单打通该通道,届时本工单的配置应改为其默认值来源。预计修改文件:
internal/core/provider/openai.goadmin/app/chorus/service.gointernal/core/provider/openai_test.goadmin/app/chorus/service_test.go(若存在对应校验测试)需求变化记录
{"resolution":"1K","aspect_ratio":"1:1"}缩小为只填{"resolution":"1K"}extra_body是全局常量而非请求级参数parseExtraBody白名单不含resolution。原判断遗漏了该校验设计与原型门禁
apps/ai/providers/openai_compatible.py:337;本工单"要解决什么"中的对照请求与 generation 18 记录resolution与随后的配置变更文档影响
需要记录两条长期事实:
/images/generations用resolution,/images/edits用size;extra_body白名单在核心域与管理端各有一份,新增键必须同步修改,否则会出现"管理端能存、运行时秒失败"。交付文档影响
验收标准
internal/core/provider/openai.go与admin/app/chorus/service.go两处白名单均包含resolution,且两处内容一致。{"resolution":"1K"}被接受,且该值出现在实际请求体中。{"model":...}、{"messages":[]}、{"n":2}、{"response_format":"url"}、{"authorization":...}、{"unknown":true}全部继续被拒绝。aspect_ratio仍被拒绝(本次未放开,需有测试锁定)。go build ./...、go vet ./...、go test ./...全部通过。provider_models.id=4的extra_body为{"resolution": "1K"};id=5保持{"size": "1024x1024"}未变。验证方式
注:
generation_outputs.width/height目前不落库(见"遗留"),尺寸需从落盘 PNG 文件头确认。完成证据
风险和回退
resolution不给aspect_ratio时上游如何决定构图未经验证。对照请求两个参数都给了,得到 1254×1254。若上游在缺少aspect_ratio时报错或退回 1536×1024,本方案不成立,应停止并重新评估。"2K",但需重新评估耗时与响应体大小。extra_body改回{}(立即生效,无需重启);代码回退直接 revert 提交,无数据迁移。实施顺序提醒
必须先上线代码、再改配置。反过来会重现 generation 18 的秒失败。
遗留(需另建工单)
generation_outputs.width与height不落库。generation 14 / 15 的实际输出为 1536×1024,但两列均为 NULL,导致尺寸只能靠读 PNG 文件头确认。开始实施(2026-08-26)
阶段:待实施 → 进行中。
前置 #62 已验收关闭,依赖满足。工作区检查:
config/local-services.yml既存改动、未跟踪的admin/config/settings.yml与一张截图均为用户已有内容,与本任务无关,保持原样不提交。实施方式
与 #62 相同的两点偏差:
extra_body是数据库配置数据,不进版本库,因此本工单无代码提交;修改通过 SQL 执行(本会话无法驱动管理端页面),config_audit_logs表在当前库中不存在,未绕过任何已实现的审计机制。顺带处理:部署二进制过期
在跑的
chorus-portal.exe编译于 2026-08-25 16:43,早于 #63 的提交52ebca2(08-26 09:07)。本次一并重新编译部署,使 #63 的错误码修复生效。这不改变 #64 的范围——extra_body由GORMCatalog.Resolve每次现查数据库,本身不需要重启即可生效;重新编译是为了 #63,在工单中记录以免混淆两者的证据。fix: 对齐 cmhub 的 images 生成尺寸参数to fix: 放开 extra_body 的 resolution 并配置文生图尺寸已停止:前提被实测推翻(2026-08-26)
阶段:进行中 → 已停止。不是"已完成"——本工单想做的事在当前 Provider 上做不到。
判别实验
代码上线后依次配置并各做一次真实生成,其余条件不变:
extra_body{}{}{"resolution":"1K"}{"resolution":"2K"}1K与2K产出完全相同的尺寸,因此不是"参数生效但值撞上默认值",而是该端点忽略resolution。耗时 150–465 秒是上游负载波动,与参数无关:generation 20 的输出(3.49 MB)甚至小于 19(3.72 MB)。
结论:该 Provider 上不存在"分辨率"这个可调项
综合此前的受控请求(
resolution:1K+aspect_ratio:1:1→ 1254×1254,1,572,516 px):size与resolution都被忽略;aspect_ratio,它只改构图比例,不改像素总量。因此本工单的目标"拿回尺寸控制权"在这个上游无法达成。上游只提供构图选项,不提供分辨率选项。
一个被推翻的中间判断
此前把受控请求的 1254×1254 归因于
resolution,据此缩小范围为"只填 resolution、排除 aspect_ratio"。现在看,起作用的恰恰是被排除的aspect_ratio。缩小范围的方向搞反了。但排除
aspect_ratio的理由依然成立:上游默认的 3:2 横构图适合现有地图类提示词,像素总量既然固定,改比例只是换形状、不会更清晰。所以即便改用aspect_ratio,也没有值得配置的东西。已回退的内容
provider_models.id=4的extra_body{}provider_models.id=5{"size":"1024x1024"}全程未动resolutionbd6732f(代码)、3d2dc96(文档)回退后
go build/go vet/go test、sync --check、check --strict均通过。白名单未保留
resolution:它是安全边界,放开一个上游根本不认的键收益为零;"别的 Provider 也许用得上"不构成现在放宽的理由,将来真有需要时按 Wiki 记录的流程重新验证后再加。保留的产出
唯一有价值的产出是文档。Wiki
Business-Rules-and-Glossary→ revisiondd1d0ceaddf4b5ba61b46a626a7e0d5135fb965e,镜像提交03ca11e,记录三条:extra_body白名单在核心域与管理端各有一份,新增键必须同步修改;只改管理端会造成"能保存但生成在毫秒内失败"(upstream_unknown、几毫秒、无上游请求)。size与resolution,像素总量固定约 157 万,只有aspect_ratio改变构图。实施过程中的事故
validateExtraBody会当场返回字段错误,不会浪费三次提交。git reset --hard,连带丢弃了工作区中与本任务无关的config/local-services.yml用户改动,已按记录的 diff 逐行还原并请用户核对。正确做法是git revert或只针对目标提交操作。遗留(需另建工单)
generation_outputs.width与height不落库。本工单全程只能靠读取落盘 PNG 文件头确认尺寸,SQL 无法直接核对。