feat: merge opus comfyui and login updates

This commit is contained in:
boos
2026-05-21 16:32:04 +02:00
parent c16479da7c
commit 9c84759498
105 changed files with 20160 additions and 1034 deletions
@@ -0,0 +1,81 @@
## ADDED Requirements
### Requirement: ComfyUI Agent 默认调用本进程 /v1
ComfyUI Agent 的三类上游调用(`/v1/chat/completions`、`/v1/images/generations`、`/v1/audio/speech`)SHALL 默认指向本进程自身,base 由 `state.config.server.host` 与 `state.config.server.port` 拼出(host 为 `0.0.0.0` 或 `::` 时改写为 `127.0.0.1`)。Agent MUST NOT 在默认配置下访问任何外部主机。
#### Scenario: 默认 base 指向本机回环
- **WHEN** `BOOSAPI_UPSTREAM_BASE` 未设置且 `server.port = 4000`、`server.host = 0.0.0.0`
- **THEN** chat / images / audio 三类调用的 base 解析为 `http://127.0.0.1:4000/v1`
#### Scenario: 显式 host 被保留
- **WHEN** `server.host = 10.0.0.5`、`server.port = 4000` 且未设置 env
- **THEN** base 解析为 `http://10.0.0.5:4000/v1`,不被改写为回环
#### Scenario: 三类调用使用同一 base
- **WHEN** Agent 在同一次会话中触发 chat、images、audio 三类调用
- **THEN** 三次请求的 base 完全一致(来自同一 `upstream_config` 调用结果)
### Requirement: env 显式设置时回退远端
当且仅当 `BOOSAPI_UPSTREAM_BASE` 设置为非空字符串时,Agent SHALL 改用该 env 值作为 base,并使用 `BOOSAPI_UPSTREAM_KEY`(若设置且非空)或内置 key 的明文作为 Bearer。该分支以下统称 `fallback-remote` 模式。
#### Scenario: env 非空触发回退
- **WHEN** `BOOSAPI_UPSTREAM_BASE = "https://api.boos.lat/v1"`
- **THEN** 三类调用的 base 解析为 `https://api.boos.lat/v1`,且 `mode = "fallback-remote"`
#### Scenario: env 为空字符串视同未设置
- **WHEN** `BOOSAPI_UPSTREAM_BASE = ""` 或 `BOOSAPI_UPSTREAM_BASE = " "`
- **THEN** base 解析回本机回环,`mode = "local"`
#### Scenario: env key 缺省时复用内置 key
- **WHEN** 设置了 `BOOSAPI_UPSTREAM_BASE` 但未设置 `BOOSAPI_UPSTREAM_KEY`
- **THEN** Bearer 使用 `comfyui-agent` 内置 key 的明文,不退化为 `proxy_token`
### Requirement: 本地调用使用内置下游 key 计费
`mode = "local"` 时,Agent SHALL 在请求头 `Authorization` 中携带 `Bearer <comfyui-agent 内置 key 明文>`。该 key MUST 与本进程 `downstream_api_keys` 表中 `name='comfyui-agent' AND user_id IS NULL` 的行一致,使所有 Agent 流量在 `usage_logs` 中以该 key 归集。
#### Scenario: chat 请求携带内置 key
- **WHEN** Agent 在本地模式下发起 `/v1/chat/completions`
- **THEN** 请求头 `Authorization` 形如 `Bearer sk-comfyui-...`,且该值等于 settings 表中 `builtin_key.comfyui_agent.secret` 的值
#### Scenario: usage_logs 归集到内置 key
- **WHEN** 一次本地模式下的 chat 请求成功
- **THEN** `usage_logs` 中存在一条记录,`downstream_key_id` 等于内置 key 在 `downstream_api_keys` 中的 id
### Requirement: status 端点暴露生效模式
`GET /api/comfyui-agent/status` 响应 SHALL 在原有字段基础上增加 `mode: "local" | "fallback-remote"` 与 `keyName: "comfyui-agent"` 两个字段;`upstreamBase` 字段 MUST 反映当前实际生效的 base(已 trim 末尾斜杠)。
#### Scenario: 默认配置返回 local
- **WHEN** 客户端在未设置 env 的情况下 GET `/api/comfyui-agent/status`
- **THEN** 响应包含 `"mode": "local"`、`"keyName": "comfyui-agent"`、`upstreamBase` 形如 `http://127.0.0.1:<port>/v1`
#### Scenario: env 设置时返回 fallback-remote
- **WHEN** `BOOSAPI_UPSTREAM_BASE = "https://api.boos.lat/v1"` 时 GET 该端点
- **THEN** 响应 `"mode": "fallback-remote"`、`upstreamBase = "https://api.boos.lat/v1"`
#### Scenario: 鉴权失败仍不暴露密钥
- **WHEN** 客户端用错误的 admin token 请求
- **THEN** 返回 401,且响应体不包含 `keyName` / `upstreamBase` 任一字段
### Requirement: 本地路由失败必须如实返回
当本地 `/v1` 没有配置对应模型路由(chat 的 `agent_model`、images 的 `gpt-image-2`、audio 的 `tts-1`),Agent SHALL 把上游返回的错误状态码 / 文案如实通过 SSE `error` 事件转发给前端,MUST NOT 在收到 4xx 时自动切到 `fallback-remote`。
#### Scenario: 本地缺少 agent_model 路由
- **WHEN** 本地模式下发起 chat,token_router 返回 404
- **THEN** SSE 流中出现 `error` 事件,message 包含上游 404 内容;后续请求仍走本地,不自动切远端