接入AGC后台模型目录与对话模型选择

新增后台 AGC 模型目录、别名、启停和默认项管理

客户端设置页恢复原状,对话框右下角按别名选择模型

服务端按稳定模型标识映射并校验实际模型白名单

修复 AGC 配套后端端口漂移、启动等待和 SpacetimeDB 版本检查

补充迁移、文档、启动与模型选择测试
This commit is contained in:
2026-09-05 19:10:49 +08:00
parent 76f0c8e58e
commit 4f3f0f24ff
52 changed files with 1942 additions and 1544 deletions
@@ -7986,7 +7986,7 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
## 2026-08-29 AGC 官方 LLM 代理与 Windows 私有路径修复
## 2026-08-29 AGC 官方 LLM 代理与 Windows 私有路径修复
- AGC 正式发行版不再让用户配置 Provider、Base URL、模型或 API Key。客户端只携带登录 access token 调用 `api-server``api-server` 按 access token 的 owner 查询 `llm_router_account`,解密服务端密文后调用固定 `https://router.genarrative.world/v1``gpt-5.6-sol` Responses 路由。真实 Router Key 不进入聊天、manifest、trace、日志、项目文件、Codex argv/环境变量或普通 IPC payload。
- AGC 正式发行版不再让用户配置 Provider、Base URL 或 API Key。客户端只携带登录 access token 调用 `api-server``api-server` 按 access token 的 owner 查询 `llm_router_account`,解密服务端密文后调用固定 `https://router.genarrative.world/v1`。模型目录由后台 owner 管理并持久化到 `agc_model_catalog`,客户端仅显示别名,在对话框右下角选择稳定标识,服务端映射实际模型名;设置页不承载模型选择或方案管理。真实 Router Key 不进入聊天、manifest、trace、日志、项目文件、Codex argv/环境变量或普通 IPC payload。
- 注册成功后视为账号已有余额;当前不实现真实扣费,LLM 代理在 Router 成功返回后再记泥点,扣费失败只记录日志,不影响已经成功的响应。注册入口和首次 LLM 请求都会幂等确保账号 Router Keyapi-server 只通过 New API 管理员 Token 执行正式“创建用户 → 查询用户 ID → 设置分组 → 登录 → 创建无限额度 token → 签发 API Key”流程并加密落库,不再生成或使用任何 Router fallback token。远端结果不确定时写入 reconciliation 标记;本地签发落库失败可安全重试,不制造第二个账号。客户端不会退回手工 Key;真实管理员 Token、注册和生产 Router 联通仍待受控部署 smoke。
- `external_api_key` 继续复用一次性明文返回和 hash/prefix 元数据链路,仅承载普通外部 OpenAPI/MCP Key。LLM Router 的 `llm-router` 用途、`llm:responses` scope、加密密文、Router account id 和固定路由元数据统一保存在 `llm_router_account`。登出、切换账号或服务器只清理进程内 access token/Provider Proxy,不删除其它账号或设备的本地/远端 Key;Router 确定返回 401/403 时标记当前账号 Key revoked。
- 后台只允许管理员通过专用 API Key 查询接口按 owner、公开用户编号、keyId、精确 prefix、名称、时间、状态和 purpose 筛选;未给出 owner/keyId/prefix 时拒绝无界扫描,永不返回 `key_hash`、密文或原始表行。通用 `external_api_key` 表浏览被拒绝。
@@ -4983,3 +4983,9 @@
- 原因:Tauri Windows bundler 执行自己的 `<tauri_tools_path>\NSIS\makensis.exe`,默认位于当前用户 `%LOCALAPPDATA%\tauri`,不使用 PATH 中预装的 `makensis.exe`Jenkins LocalSystem/systemprofile 的 AppData 可能无法启动该缓存程序。
- 处理:Windows 专用 Tauri 配置设置 `bundle.useLocalToolsDir: true`,把工具缓存到 `src-tauri/target/.tauri/NSIS`;Jenkins 预检验证实际用户、项目工具目录可写,并在构建失败时打印实际缓存路径和绝对路径执行结果。
- 验证:不要把 PATH 中 `makensis` 可发现当作 Tauri bundler 工具可执行的充分证据;需要在 Windows Agent 上检查 `target/.tauri/NSIS/makensis.exe`、ACL、EDR/Defender 和直接 `-VERSION` 结果。
## AGC 前端等待超时与 worker 端口冲突
- `backend` 模式需要同时探测 API、worker 和必要的 SpacetimeDB 端口。只让 API 漂移会遗漏仍被旧进程占用的 worker 端口。
- AGC Vite 在配套后端全部就绪后才启动。Tauri 的前端等待超时及随后的 `code=143` 可能是 worker 先失败导致的连带退出,应先检查 `.app/dev-stack.json` 各服务状态和监听进程,不能直接归因于 Vite 或数据库。
- 外层 `start-tauri-dev.mjs` 应在启动 Tauri 前完成配套开发服务准备,并统一收束自有服务进程树;不要让冷编译和数据库发布挤占 Tauri 的前端就绪等待。自动发布必须保留数据库,不能靠清库解决启动问题。
- CLI 与 standalone 可能是两个独立软链接。必须同时核对 `spacetime --version``spacetimedb-standalone --version`,不能把 CLI 的版本记录当作宿主版本证明;PATH 中存在宿主时启动器检查两者一致。更换宿主前停机备份数据,按原目录启动,不通过清库处理版本错配。
@@ -0,0 +1,17 @@
# AGC 后台模型别名与对话选择
## 契约
- 后台 owner 在“AGC 模型”维护列表;每项包含稳定 `id`、必填 `alias`、服务端 `modelId``enabled`。默认项必须启用。标识唯一,别名唯一,列表最多 32 项。
- 配置保存到私有 `agc_model_catalog` 单例表,使用 revision 乐观锁,重启及多 api-server 实例共享同一事实。缺少配置时使用初始目录,高质量对应 `gpt-6-astra`,快速对应 `gpt-5.6-luna`
- `GET/PUT /admin/api/agc-models` 仅 owner 可用,返回完整配置;PUT 携带上次读取的 revision,冲突拒绝覆盖。
- `GET /api/llm/models` 返回启用项的 `id/displayName``defaultModelId`,不返回实际模型名、Router 目录、凭据或能力原始数据。
- AGC Responses 请求的 `model` 是稳定目录标识。服务端按当前目录映射实际模型名;未知、停用项拒绝,不回退其它模型。旧客户端无 AGC 标记时使用后台默认项。
- 输入框右下角选择模型,只显示别名;选择保存到客户端配置 `selectedModelId`,从下一次请求生效。加载失败或选项停用时禁用提交并允许刷新,不显示实际 ID 作为兜底文案。
- 设置页恢复到布局改版前的官方代理版本,不包含模型管理或模型选择,保留配置安全清理和官方代理锁定。
## 验收
- 目录领域校验、未知/停用模型拒绝、客户端响应不包含实际模型名。
- 后台鉴权、持久化 revision 冲突处理;客户端选择保存后重新读取,设置保存不覆盖选择。
- AGC/admin-web 类型检查与定向测试、编码检查、Rust 定向检查、schema 一致性与 diff 检查。
@@ -649,6 +649,13 @@ Responses 的终态载荷既是工具调用的恢复源,也是正文的恢复
- 作用:记录用户与官方 LLM Router 账号的稳定映射、API Key 核心字段、账号生命周期、远端账号元数据、订阅检查状态、重试 / 对账状态和加密凭据版本。Router 明文 Key 只在 api-server 进程内短暂存在,数据库仅保存加密凭据;账号读取和写入统一通过对应 procedure 与 `spacetime-client` facade 完成。
- 索引:`by_llm_router_account_owner_route` 用于按 owner 与路由来源读取账号;`by_llm_router_account_status_next_retry` 用于按状态和下次重试时间扫描待对账账号。
### `agc_model_catalog`
- 私有单例表,主键 `id=0`,保存 `catalog_json``revision``updated_at`;不存凭据。
- `read_agc_model_catalog` / `save_agc_model_catalog` 只接受已登记的 runtime service identity,保存使用 revision 乐观锁。
- 后台 owner 通过 `GET/PUT /admin/api/agc-models` 管理稳定标识、必填别名、实际模型名、启用状态和默认项;客户端 `GET /api/llm/models` 仅返回启用项的稳定标识和别名。
- Responses / Chat 请求按目录解析模型;未知或停用项拒绝。AGC 的 `platform-default` 请求标识使用目录默认项。详细契约见 `technical/【技术方案】AGC后台模型别名与对话选择-2026-09-05.md`
### `error_report`
- Rust 结构体:`ErrorReport`
@@ -12,6 +12,10 @@
## 本地启动
AGC `backend` 模式与 `all` / `api-server` 一样,必须同时探测 API 和 BgFilter worker 端口,漂移后的 worker 地址同时传给 API、worker 和 readiness 检查。不能因为旧 worker 的 `/readyz` 可访问,就把新启动失败的同端口 worker 视为就绪;AGC 前端会等待完整配套后端,worker 失败可能最终表现为 Tauri 等待前端 180 秒超时。
`npm run agc` 外层启动器先执行 `agc:serve` 并等待前端与配套后端就绪,再启动 Tauri,同时清空本次 CLI 的 `beforeDevCommand`,避免重复拉起服务和把数据库发布时间计入 Tauri 的 180 秒前端等待。准备阶段最多等待 660 秒(后端门禁仍为 600 秒),退出时清理本次启动的服务树,不停止复用的服务。AGC 自动发布显式使用 `--preserve-database`,schema 冲突须人工确认迁移,不自动清空数据。
安装依赖:
```bash