新增 app/providers/openai/:client 传输(JSON + multipart)、errors 错误映射、 models 厂商 DTO、capabilities 尺寸算术约束、tasks 同步→异步桥、image 图片业务。 装配与配置同步接入,缺 OPENAI_API_KEY 时跳过装配、服务仍可启动。 与火山视频的三处根本差异及其处置: - 接口同步(无任务 ID、无查询端点)→ SyncTaskRegistry 在本服务内部吸收, 对外仍是 ADR-023 §4 的两段式提交/轮询。代价:本服务从此持有状态,进程重启 丢在途任务,且横向扩容前须先解决任务 ID 只在签发进程内有效的问题。 - 产物是 base64 字节而非 URL → 无过期问题,但字节只在内存里。asset_url 放 data URI 仅为满足领域不变式,绝不能原样写进 media.assets.external_url。 - 图生图走 multipart → 先下载参考图再上传;下载失败与超限按参数错误同步拒绝, 不变成注定失败的后台任务。 两处需要记住的判断: - 尺寸上限「3840x2160」文档未说清是逐边还是按像素。逐边理解会禁掉所有高于 2160 的竖图,而 1024x1536 是文档明示的标准竖图,故必然过严。采用最长边 ≤3840 且总像素 ≤3840×2160,已在 capabilities.py 与取证页标为推断。 - 两份文档都没有错误码表,故 errors.py 以 HTTP 状态码为主、type/code 为辅, 顶部标注「未经文档证实」。429 无线索时按限流而非配额耗尽(猜成配额会把可 重试的限流判死);400 无线索时归服务端错误而非内容被拒(错报会让用户去改 一个其实没问题的提示词)。 一处死锁已修并回归钉住:SyncTaskRegistry 原用 add_done_callback 记录完成时刻, 而快速完成的任务在注册时已 done,回调便同步地在持有非可重入锁的线程里执行。 改为首次被观察到时惰性记录。 测试 166 → 271(+105)。四道门禁逐条读退出码,全绿。 产物转存仍阻塞于存储决策(ADR-023 §7),图片模型因此未播种进 V7 目录。
This commit is contained in:
+30
-1
@@ -32,6 +32,18 @@ info:
|
||||
`service` 类属我方 bug 或配置问题(除 `internal_error`/`provider_unavailable`
|
||||
外均不可重试);`provider` 类一律以 `retry` 字段为准,不要自己解读厂商码。
|
||||
|
||||
## 一处与服务商形态有关的说明
|
||||
|
||||
**服务商可能是同步的。** 火山的视频接口本身异步(提交返回任务 ID);OpenAI 的
|
||||
图片接口是**同步**的——一次请求等到底,没有任务 ID 也没有查询接口。该差异由本
|
||||
服务在内部吸收(ADR-023 §4),故本契约对两者形状完全一致。
|
||||
|
||||
代价如实登记:同步型供应商的在途任务只能记在本服务内存里,**进程重启会丢失**,
|
||||
之后查询返回 `task_not_found`。那次调用可能已经完成并计费,而同步接口没有任务
|
||||
ID 可供事后查询,故该窗口**无法靠"再查一次"弥补**,只能由调用方的
|
||||
`max_attempts` 兜住。并发在途任务达上限时提交返回 `provider_unavailable`
|
||||
(503,可重试)而非 `invalid_request`。
|
||||
|
||||
## 鉴权
|
||||
|
||||
所有端点要求服务身份 JWT:`Authorization: Bearer <token>`。本服务强制校验
|
||||
@@ -192,8 +204,25 @@ components:
|
||||
resolution:
|
||||
type: [string, 'null']
|
||||
description: |
|
||||
缺省 `720p`。按模型预校验:2.5 无 4k,2.0 系列有。
|
||||
缺省 `720p`。按模型预校验:2.5 无 4k,2.0 系列有。**视频路径专用**。
|
||||
example: 720p
|
||||
width_px:
|
||||
type: [integer, 'null']
|
||||
description: |
|
||||
**图片路径专用**的像素宽。与 `height_px` 必须同时给,否则交由模型自选
|
||||
(半个尺寸不如不给)。
|
||||
|
||||
两家服务商的尺寸表达方式不同:火山用「分辨率档 + 宽高比」
|
||||
(`resolution` + `ratio`),OpenAI 用 `WIDTHxHEIGHT` 像素串。契约同时
|
||||
保留两种而**不强行统一**——任何统一都会在某一侧失真:把 720p+16:9 折成
|
||||
像素会丢掉「档位」语义,把像素折成比例会丢掉精确值。
|
||||
|
||||
OpenAI 侧的算术约束会在本服务**本地预校验**:宽高都须被 16 整除、
|
||||
宽高比在 1:3 ~ 3:1 之间、不超过 3840x2160(超过 2560x1440 属服务商
|
||||
标注的实验性范围)。违规请求以 `invalid_request` 拒绝,不花一次往返。
|
||||
height_px:
|
||||
type: [integer, 'null']
|
||||
description: 见 `width_px`。
|
||||
duration_sec:
|
||||
type: [integer, 'null']
|
||||
description: |
|
||||
|
||||
Reference in New Issue
Block a user