Merge branch 'master' into fix/agc-canvas-json
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 6m49s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Successful in 7m3s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m21s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 7m56s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Successful in 6m50s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 3m1s
Project CI / Frontend tests (pull_request) Successful in 4m38s
Project CI / Repository checks (pull_request) Successful in 3m43s
Project CI / Backend tests (pull_request) Successful in 8m30s
Project CI / AI game creator shell web tests (pull_request) Successful in 4m7s
Project CI / Native shell tests (pull_request) Successful in 25m34s
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 6m49s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Successful in 7m3s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m21s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 7m56s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Successful in 6m50s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 3m1s
Project CI / Frontend tests (pull_request) Successful in 4m38s
Project CI / Repository checks (pull_request) Successful in 3m43s
Project CI / Backend tests (pull_request) Successful in 8m30s
Project CI / AI game creator shell web tests (pull_request) Successful in 4m7s
Project CI / Native shell tests (pull_request) Successful in 25m34s
This commit is contained in:
@@ -151,7 +151,7 @@ Authorization: Bearer <internal-token>
|
||||
- 当前部署只有一个配置内私有 OSS bucket,因此请求只传 `sourceObjectKey`,子 worker 从自身 OSS 配置取 bucket 并生成短期签名 URL。
|
||||
- 如果未来确实支持多个 bucket,新增字段也必须由服务端 allowlist 校验;不能接受调用方提供任意下载 URL。
|
||||
- `backgroundMode` 只允许 `flat / complex`;`segModel` 继续沿用当前 `birefnet / anime-seg` allowlist;complex 固定使用当前参数组合。
|
||||
- `screenColor` 只对 flat 必填;complex 不得误接 flat 参数,两种模式的熔断状态必须隔离。
|
||||
- `screenColor` 在 flat 下可省略,也可传 `auto` 或 `#RRGGBB`;省略或 `auto` 由 BgFilter 自动识别。complex 不得携带背景色,两种模式的熔断状态必须隔离。生成角色、图集等既有链路继续传已确定的背景色。
|
||||
- `maxQueueWaitMs` 与 `callBudgetMs` 都是相对预算,不是跨机器绝对时间。前者从 admission 起约束排队阶段(worker 还会用 §5.2 的动态估计对其取 min);后者从取得 provider permit 起计时,覆盖签名、两次 attempt、结果校验和响应构造。`callBudgetMs` 是父侧按 `N / est` 公式算出的“配置指纹”,仅作核对:worker 始终以自己按同一公式派生的值执行,不一致时不拒绝请求,而是记录 warn 日志并递增漂移指标。发布调优 N / est 时新旧进程共存的瞬态漂移因此不会误伤在途任务;持久性漂移的硬拦截由部署脚本的共享 env 对齐校验承担。
|
||||
- JSON body 设置很小的固定上限;源图字节不进入该 JSON。
|
||||
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
# AGC 抠图模式与背景色透传方案
|
||||
|
||||
## 目标
|
||||
|
||||
主站编辑器保持现有前端行为(继续使用 `complex`),同时扩展 External v1 抠图接口和 AGC 客户端,使客户端可以选择 `complex` / `flat`,并把 `screenColor` 原样交给 BgFilter。`complex` 用语义分割识别前景,`flat` 用于纯色背景抠图;确定背景为纯色时优先使用 `flat`。`auto` 的背景色识别完全由下游服务负责,主站不读取图片、不调用模型决策颜色、不生成颜色兜底值。
|
||||
|
||||
## 当前 BgFilter 契约
|
||||
|
||||
已登录生产服务器核对 `/root/BGfilter`,当前代码版本为 `f1a0833`,运行进程为 `python -m uvicorn app:app --host 0.0.0.0 --port 6006 --workers 1 --no-access-log`。服务契约为 `POST /remove-background` multipart:
|
||||
|
||||
- `background_mode`:可选,`flat` 或 `complex`;
|
||||
- `screen_color`:可选,支持 `#RRGGBB`、`auto` 或省略;省略/`auto` 时由 BgFilter 从图片边框自动检测;
|
||||
- `complex` 模式忽略 `screen_color`;
|
||||
- 自动检测失败由 BgFilter 返回 400。
|
||||
- 若配置 `BGFILTER_AUTH_TOKEN`,必须发送 `X-Genarrative-Image-Token`;缺失或错误返回 401;未配置时该接口不在服务层做 token 校验。
|
||||
|
||||
主站向 BgFilter 发送 `#RRGGBB` 时保留 `#`,`auto` 也原样发送,不做所谓的“hex 转换”。
|
||||
|
||||
服务器行为:`screen_color` 在 `auto` 或省略时由服务自动检测;`#RRGGBB` 用作指定背景色。`background_mode` 缺省在 BgFilter 侧为 `flat`,因此主站必须为 External v1 旧请求显式归一化为 `complex`,不能把下游服务的默认值直接当成主站默认值。
|
||||
|
||||
## External v1 请求契约
|
||||
|
||||
接口保持:
|
||||
|
||||
```text
|
||||
POST /api/external/v1/editor/images/background-removals
|
||||
```
|
||||
|
||||
新增可选字段:
|
||||
|
||||
| 字段 | 取值 | 缺省/行为 |
|
||||
| --- | --- | --- |
|
||||
| `backgroundMode` | `complex`、`flat` | 不填按 `complex`,保证旧客户端兼容 |
|
||||
| `screenColor` | `auto` 或 `#RRGGBB` | 不填则不向 BgFilter 发送该字段 |
|
||||
|
||||
组合规则:
|
||||
|
||||
1. 不传新增字段:按 `complex` 执行。
|
||||
2. `complex` 不允许传 `screenColor`,返回 400。
|
||||
3. `flat` 可以传具体 `#RRGGBB`、`auto`,也可以省略颜色。
|
||||
4. 模式和颜色严格按原值校验;非法值、空字符串、前后空格和大写 `AUTO` / `FLAT` 返回 400。十六进制颜色的字母允许大小写。
|
||||
5. 主站只做格式和组合校验;`auto` 不在主站解析,直接转发给 BgFilter。
|
||||
6. HTTP 请求中的 `null` 视同省略;模式省略时提供非 null 颜色同样违反 complex 约束。客户端 MCP 可选参数应省略,不传 null。
|
||||
|
||||
格式或组合错误在入队前返回 400;BgFilter 自动检测失败发生在异步执行阶段,任务通过既有失败状态收口,不把已接受的 202 改成同步 400,不启动其他抠图方式兜底。
|
||||
|
||||
OpenAPI 与客户端工具的对外说明只描述模式用途、参数约束和调用方可见的结果;provider 选择与兜底策略保留在内部技术方案中,不写入对外 description。
|
||||
|
||||
主站前端继续不传新增字段,因此用户行为不变。
|
||||
|
||||
## AGC 客户端改动
|
||||
|
||||
`agc_remove_background` 增加可选参数:
|
||||
|
||||
```json
|
||||
{
|
||||
"sourceLocalAssetId": "...",
|
||||
"assetName": "...",
|
||||
"backgroundMode": "flat",
|
||||
"screenColor": "auto"
|
||||
}
|
||||
```
|
||||
|
||||
客户端保留旧参数调用;新字段不填时不改变旧调用语义。客户端不读取图片、不自动选色、不把 `auto` 改写为具体颜色,使用原有 Bearer 认证、幂等键和队列返回模型。
|
||||
|
||||
工具 schema、桥接参数校验和随包 `agc-client-projection` Skill/契约说明必须保持一致。模式与颜色属于请求意图,必须参与客户端幂等指纹;同一图片与名称的不同模式不能复用同一次请求。缺省 complex 且没有颜色时保留既有指纹。主站在默认值归一化之前计算 External 请求指纹,缺失的新字段不序列化,避免旧请求重放发生冲突。
|
||||
|
||||
## 实施任务
|
||||
|
||||
### 任务一:冻结 BgFilter 契约
|
||||
|
||||
记录服务器已支持的模式、颜色格式、自动检测和错误行为。不得把 SSH 地址、服务器凭据写入客户端或公开契约。
|
||||
|
||||
### 任务二:更新主站 DTO 与 OpenAPI
|
||||
|
||||
为 External v1 和内部任务 DTO 增加可选字段,更新 `docs/openapi/genarrative-external-v1.openapi.json`,写明默认值、组合约束和 400 响应。
|
||||
|
||||
### 任务三:更新主站归一化与队列
|
||||
|
||||
缺省模式归一化为 `complex`;`complex + screenColor` 拒绝;`flat` 允许颜色、省略或 `auto`。队列保存字段,worker 始终发送 `background_mode`,仅在调用方提供颜色时发送 `screen_color`,值原样透传。
|
||||
|
||||
### 任务四:更新 AGC 客户端
|
||||
|
||||
增加参数 schema、请求体字段和本地校验,更新 Skill、projection contract 与测试。旧客户端请求必须继续有效。
|
||||
|
||||
### 任务五:联调与验收
|
||||
|
||||
覆盖旧请求、`flat + auto`、`flat + #RRGGBB`、`flat` 不传颜色、`complex`、`complex + screenColor` 和非法值;使用真实 BgFilter 验证 multipart 字段及自动检测错误传播。
|
||||
|
||||
## 依赖、发布与回滚
|
||||
|
||||
先发布兼容的新主站,再发布支持新参数的 AGC 客户端。主站前端无需发布改动。若联调失败,客户端可回退为只传旧字段,主站仍按 `complex` 处理;主站回滚时不改变旧字段语义。
|
||||
|
||||
## 验收证据
|
||||
|
||||
2026-09-16 实测:
|
||||
|
||||
- 主站 `cargo test -p api-server background_removal`:36 项通过,覆盖非法请求入队前拒绝、缺省 complex、队列参数保留、旧请求指纹、父侧内部 RPC 和 provider multipart。
|
||||
- `cargo test -p api-server bgfilter`:52 项通过,包括 flat 的 auto/省略/具体颜色以及既有生成链路。
|
||||
- `exported_openapi_json_contains_external_editor_routes_and_security` 契约测试通过。
|
||||
- 客户端 `agent::direct_tools_mcp::tests` 18 项、`agent::skill_pack::tests` 4 项与抠图幂等指纹测试通过;Skill manifest 内容指纹已同步。主站与客户端 rustfmt、文档索引、编码及 diff 检查通过。
|
||||
- 真实 BgFilter(版本 `f1a0833`):使用进程内凭据串行请求 `flat + auto`、flat 省略颜色、`flat + #CFEFFF`、complex;四组均返回 200、512×512 RGBA PNG,alpha 范围均为 0–255。
|
||||
- 无纯色背景的随机噪声图片使用 flat + auto 返回 400,确认自动识别失败要求调用方提供颜色。测试没有修改服务器代码或配置。
|
||||
- 本地 `npm run dev:api-server` 已尝试,但当前配置指向的 SpacetimeDB 不可连接,服务停留在启动恢复重试,`/healthz` 未通过;已结束本次启动。完整登录客户端 → 主站持久化队列 → 结果回写的运行时验收尚未完成,不能用真实 BgFilter 的独立测试代替。没有部署本次主站或客户端代码。
|
||||
Reference in New Issue
Block a user