Merge branch 'master' into style/better-error-report
This commit is contained in:
@@ -19,6 +19,8 @@
|
||||
|
||||
## AI 游戏创作与 Agent Runtime
|
||||
|
||||
- [LLM 累计额度结算](./technical/【技术方案】LLM累计额度结算-2026-09-05.md):Router 累计额度、首次基线与原子钱包结算。
|
||||
|
||||
- [AI 游戏创作智能体 App 实施计划](./technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md):当前 DirectProject、受控语义工具、UI workflow、资源和运行时合同。
|
||||
- [DirectProject 客户端 Skill 与 MCP 扩展导入方案](./technical/【技术方案】DirectProject客户端Skill与MCP扩展导入方案-2026-08-31.md):客户端扩展导入、按独立 Skill/MCP 拆分、命名、启用和启动时注入边界。
|
||||
- [AGC 客户端更新检查与下载](./technical/【技术方案】AGC客户端更新检查与下载-2026-08-31.md):启动版本检测、OSS 清单格式和下载约定。
|
||||
|
||||
@@ -41,6 +41,17 @@
|
||||
- 验证方式:运行 `npm run check:native-shells`,确认 H5 HostBridge 调用链静态扫描不再引用已删除文件;同时运行编码、格式和 diff 检查。
|
||||
- 关联材料:Native shell tests #5758、主站合并提交 `025f62729`、已删除的 `PlatformProfileQrScannerModal` 文件。
|
||||
|
||||
---
|
||||
|
||||
## 2026-09-02 Direct 过程卡按回合阶段状态驱动
|
||||
|
||||
- 背景:DirectProject 结果卡把工具活动词、中间文本和真实回复增量都当成“实时回复”,标题随最近一次事件跳动;上游常整包返回正文时还叠加合成打字机,用户看到的是行为名而非当前阶段。
|
||||
- 决策:Direct 过程卡顶部标题只由 `GameCreatorDirectTurnUpdateStatus` 决定(accepted=需求已接收 / running=任务执行中 / streaming=回复生成中 / finalizing=结果整理中 / completed=回复已生成 / failed=处理失败),小字只展示当前正在执行的具体内容并统一加“正在”前缀;真实回复增量(AccumulatedText)才标记 streaming,计划、推理、工具输出与 Activity 一律 running。生成中的累计回复直接作为 assistant 消息气泡在会话列表中原位更新,不再拼进过程卡;进入 finalizing / completed 时保留完整累计回复直到正式消息接管,失败时清除未完成正文。移除合成打字机回放;工具说明/中间文本不再触发 streaming。计划/推理通知收敛为 `preparing` 活动并在界面显示“正在思考中”,原始推理/计划正文不进入 UI,思考期的心跳按 1.2s 限流。命令/文件/工具执行细节与回复流解耦,`stream=false` 时仍展示在过程卡;MCP 工具按用户语义显示(例如 `agc_write_file` 为“正在写入文件:<项目相对路径>”、图片/素材/搜索/试玩分别显示生成、导入、搜索、试玩等动作),未知工具只显示“正在调用工具”不暴露内部工具名;命令显示“正在执行命令:<命令>”,验证类命令显示“正在验证游戏:<命令>”。同一活动后续无正文的心跳不得用通用文案覆盖已展示的具体工作。展开/收起是同一 `project + clientTurnId` 内的持久状态,内容更新不重置,切换新回合才收起;展开详情的滚动条轨道和角落保持透明。
|
||||
- 影响范围:`apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime.rs` 的 DirectProject observer、`apps/ai-game-creator-shell/src/App.tsx` 的事件投影、`ProjectSupervisorView` 过程卡渲染与对应 AppSurface 回归。
|
||||
- 验证方式:Rust 单测证明只有开启流式时的 AccumulatedText 是 streaming、preparing 通知只产生 thinking 活动词且不携带原始推理文本、执行细节在 `stream=false` 时仍保留,并覆盖全部 AGC MCP 工具语义、未知工具不泄漏、绝对路径 / 上跳路径不展示;AppSurface 覆盖接受态、preparing 显示“正在思考中”、running 长文本展开、command-exec 与写文件心跳不覆盖具体工作、streaming 正文进入 assistant 气泡且过程卡只显示阶段、同一回合后续 running 不覆盖正文也不收起、失败后清除未完成正文、正式消息接管不重复;样式核对确认展开详情的滚动条轨道与角落透明;AGC typecheck、全量 appSurface、rustfmt、`npm run check:encoding`、`git diff --check` 通过。
|
||||
- 关联文档:`docs/technical/【技术方案】Direct回合行为审计账本-2026-08-31.md`、分支 `feat/agc-llm-router-official-chain`。
|
||||
|
||||
---
|
||||
## 2026-09-02 GDD 审批卡的后台 hydrate 不抢占已加载决定
|
||||
|
||||
- 背景:项目页首次加载和运行态刷新可能并发 hydrate。卡片已经显示后,短暂的 `hydrateBusy` 会让已打开的评论弹层提交按钮瞬时变灰,用户无法提交已输入的修改意见。
|
||||
@@ -7971,3 +7982,55 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
|
||||
- UI 编辑器导出的 `ui/generated-*.js` 是派生本地产物。代码生成只写文件,绝不推进项目 revision、UI State revision、manifest 阶段或 Runtime 验证门;写入失败只返回生成错误,不能把生成文件写入冒充项目 mutation。
|
||||
- 生成文件名保留可读清洗前缀,并追加 asset ID 的 SHA-256 摘要前缀以避免不同 ID 碰撞;不迁移既有旧路径,调用方需在采用新命名后使用新返回路径。
|
||||
- Radial90 的前端预览与 Rust 导出统一使用角点映射和顺时针起始角规则,顺时针填充从角点前一条边开始,避免两端渲染偏移。
|
||||
|
||||
## 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`。模型目录由后台 owner 管理并持久化到 `agc_model_catalog`,客户端仅显示别名,在对话框右下角选择稳定标识,服务端映射实际模型名;设置页不承载模型选择或方案管理。真实 Router Key 不进入聊天、manifest、trace、日志、项目文件、Codex argv/环境变量或普通 IPC payload。
|
||||
- 注册成功后视为账号已有余额;当前不实现真实扣费,LLM 代理在 Router 成功返回后再记泥点,扣费失败只记录日志,不影响已经成功的响应。注册入口和首次 LLM 请求都会幂等确保账号 Router Key;api-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` 表浏览被拒绝。
|
||||
- Windows 私有路径严格拒绝 reparse/symlink、非普通对象、路径类型冲突和候选路径冲突。只有本次调用新建的目录/临时文件可在普通进程内初始化 owner;owner 已正确但仅继承 ACL 不合规时,正式 prepare 入口先完成归属校验,再通过当前用户私有、禁止继承、单一 ACE 的 DACL 收紧。用户通过原生选择器明确选中的项目根/文件,或 AGC managed 路径,在发现 owner/DACL 权限不足时由一次性 UAC helper 将普通对象接管为当前 TokenUser 并复核;取消/失败保持失败关闭,未经过正式选择或项目根入口的内部路径不得触发任意提权。
|
||||
- 规划、Runtime sidecar、UI workflow、资源桥、Skill 隔离目录和图片读取统一经过私有路径准备,并在原子写入后复核类型、owner/DACL 与文件身份。真实 Windows UAC、foreign owner 修复、继承 DACL 收紧、注册后 Router 签发和生产 `/v1/responses` 联通仍需在受控实机/部署环境验证。
|
||||
|
||||
## 2026-08-31 LLM Router 独立账号与后置扣费修订
|
||||
|
||||
- 每个 Genarrative 用户在认证成功后都必须幂等准备独立 Router 账号:api-server 使用管理员 Token 创建随机密码普通用户,查询用户 ID,设置用户 `group=taonier`,登录、创建或复用固定标识 `agc_auto_generate` 的无限额度 Token(Token/API Key 使用 `default` 分组;发现旧 Token 为其它分组时先更新为 `default`)并签发 API Key。Router 账号用户名、随机密码、access token(如需)和 API Key 作为一个服务端加密 bundle 保存到 `llm_router_account.credential_ciphertext`,脱敏账号信息和 API Key 核心字段保存到 `llm_router_account`;客户端和普通用户永远不可见 Router Key。管理员 Token 仅存在 api-server 私有配置,不写入数据库或日志;Router 凭据只来源于这条正式账号流程。
|
||||
- 该账号 provisioning 使用持久 saga 状态:远端注册、登录、token 或 Key 签发结果不确定时进入 `unknown` / `reconciliation_required`,禁止重复注册;远端 Key 已确定签发但本地 `llm_router_account` 写入失败时保持 `key_issued`,后续使用确定 key id 重试落库。Router 确定返回 401/403 时撤销当前 Key 并把账号状态置为 `retryable`,复用已保存的账号密码重新签发替代 Key。
|
||||
- AGC 调用固定为客户端 access token -> api-server -> Router。计费读取账号 `used_quota`,每 50000 quota 扣 1 泥点,美元数值乘 10、不乘汇率。首次模型调用前以当前累计额度完整建立免追扣基线,之后调用前后同步;扣钱包、写 `llm_router_consume` 流水与推进已结算额度同事务完成。小数和余额不足未支付部分继续累计,失败或重复同步不推进已结算额度,不使用本地 WAL 或余数队列。完整合同见 `docs/technical/【技术方案】LLM累计额度结算-2026-09-05.md`。
|
||||
- AGC 状态面收口:Tauri `check_game_creator_llm_config`、`/llm-status` 与 `/llm-routes` 只返回账号凭据状态、官方路由锁定状态和运行参数;不序列化 Router 地址、模型、协议名或任何密钥/凭据字段,内部固定路由仅留在运行时配置与服务端代理中。
|
||||
|
||||
## 2026-09-01 LLM Router provisioning 环境隔离与测试门禁
|
||||
|
||||
- api-server 读取 `GENARRATIVE_ENV`;只有 `production` 才允许固定官方 Router 控制面,生产缺管理员 Token 在启动时告警并在新账号 provisioning 时拒绝。`development`、`test`、`container` 等非生产环境默认只允许 loopback Router,避免测试调用线上用户服务创建真实账号、冲突用户名或消耗额度。
|
||||
- 删除进程级 Router fallback Key 语义。测试如需模拟已完成账号,只能注入显式 owner-scoped、loopback 的“已 provisioning”fixture;没有 fixture 必须走 `external_api_key` / `llm_router_account` 查询与正式 provisioning,不能直接访问上游。新生成的 pending 凭据不再被误判为可复用远端账号。
|
||||
|
||||
## 2026-09-01 LLM Router 公共实例与独立数据库的稳定账号恢复
|
||||
|
||||
- Router 为公共实例、各部署数据库独立时,Router 用户密码改为由固定版本 provisioning secret、Router 控制面 origin 和 owner 稳定推导;所有能操作同一 Router 的部署必须使用同一 secret。该 secret 当前按临时过渡方案固定在 api-server 服务端实现,客户端、数据库明文、日志和普通请求不接触;后续再迁移到部署密钥管理并保留 `credential_version`。
|
||||
- 数据库没有本地 `llm_router_account` / `external_api_key` 行时,先用稳定用户名/密码查询并登录远端账号;只有确认用户不存在才注册。登录成功后先按固定名称查询 Router token,存在则复用,不存在才创建,避免不同部署因本地数据库为空而重复创建远端账号或 token。注册返回冲突时必须重新查询,不得盲目重试。
|
||||
|
||||
## 2026-09-01 Router 账号可恢复标识与跨开发库复用
|
||||
|
||||
- Router 用户名固定为 `agc_user_` 加 11 位 URL-safe SHA-256 短码,短码由完整 owner `user_id` 稳定派生,以满足 New API `username` 20 字符上限;完整 owner `user_id` 同步写入 New API 用户 `remark`,Router 统计可据此直接回溯对应的 Genarrative 用户,即使某个部署的本地数据库被重置。
|
||||
- Router 用户密码只由 owner user id 与固定版本 provisioning secret 稳定派生,不绑定 route origin;所有连接同一公共 Router 的开发/生产部署都能计算同一密码。
|
||||
- Router 用户下用于 AGC 的 Token 固定标识为 `agc_auto_generate`。各部署登录后先按该标识查询并复用 Token,再通过 Token Key 接口取得同一把 API Key;不存在时才创建 Token,避免每次 provisioning 新建 Key。
|
||||
|
||||
## 2026-09-01 Router 订阅按账号准备续期
|
||||
|
||||
- 每次 api-server 准备或复用用户 Router API Key 时,在账号登录成功后、Token/API Key 流程继续前查询 New API 管理订阅接口。固定套餐为 `plan_id=1`:没有 active 订阅、订阅已过期或 `end_time - now <= 24h` 时创建一条管理员订阅;剩余超过 24 小时则复用现有订阅。`end_time` 按 New API 合同解释为 Unix 秒。
|
||||
- 检查锚点固定为认证后的账号准备、显式 Router Key 准备和 LLM 请求解析凭据路径,不放入 Responses 流式 chunk;同一 api-server 进程继续复用 owner 级 provisioning mutex,跨实例重复订阅幂等性依赖 Router 端后续约束或部署侧串行化。
|
||||
- 订阅查询/创建只使用 api-server 私有管理员 Token;管理员 Token 缺失时保留启动 Warning 并跳过续期检查,不能伪造客户端凭据或把 Router Key 暴露给客户端。
|
||||
|
||||
## 2026-09-02 LLM Router 零泥点前置门禁
|
||||
|
||||
- AGC LLM 对话入口在解析 Router 凭据和访问上游前先读取用户 `wallet_balance`。余额为 `0` 时直接返回 `409 MUD_POINTS_INSUFFICIENT`,客户端显示“泥点余额不足”;不创建、续期或使用 Router 账号。余额读取失败同样失败关闭,返回“泥点余额暂时不可用”。
|
||||
- 余额大于 `0` 的请求继续走 Router,成功后仍按 best-effort 后置结算;退款占用、冻结或扣费时余额不足的处理继续由钱包事务和既有结算规则负责。
|
||||
|
||||
## 2026-08-29 DirectProject 受控联网搜索默认与边界
|
||||
|
||||
- 正式产品本次只覆盖 `DirectProject` 单 Codex Agent。`Provider`、`ToolHost`、`DirectHome` 不是 Agent,也不是本次联网主链路;不新增全路由联网或工具桥。唯一受控联网工具为 `agc_tools.agc_web_search`,链路固定为 Codex MCP 工具目录 -> 客户端 loopback `DirectToolBridge` -> 有界 Bing RSS HTTPS -> 过滤 / 脱敏 -> MCP 结果回传。
|
||||
- Codex app-server 的 `web_search=\"disabled\"` 安全校验保持不变。`llm.webSearchEnabled` 在 DirectProject 只控制受控 AGC 工具暴露与执行;状态面必须同时显示受控联网状态和“Codex 原生 web_search 关闭”,不能混称为 Provider 原生搜索。
|
||||
- 配置契约提升为 `game-creator-config.v2`:新模板默认 `stream=true`、受控搜索开启;无版本旧 DirectProject 配置仅在省略 `webSearchEnabled` 时把历史默认补为开启,旧配置显式 `false` 不覆盖,v2 显式 `false` 同样保留;Provider / Anthropic 未提供搜索覆盖时保持关闭。本地覆盖配置只补 schema 版本,不凭不完整 overlay 推断或写入 `agentMode` / 搜索布尔值;未知版本失败关闭。
|
||||
- 搜索结果始终是不可信外部输入,只可作为资料;工具 schema、参数、客户端权限、Agent 身份、系统规则和工具协议不得由网页内容修改。搜索结果与状态投影不携带 API Key、请求头、宿主绝对路径或 Provider 原始错误正文。
|
||||
- 验证锁定:`configuration`、`direct_tools_mcp`、`direct_tool_bridge`、`codex_app_server` 定向 Rust 测试,以及前端状态格式化 / AppSurface 测试;真实 Provider 登录态与真实公网搜索仍需单独现场 smoke。
|
||||
|
||||
@@ -4983,3 +4983,11 @@
|
||||
- 原因: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 中存在宿主时启动器检查两者一致。更换宿主前停机备份数据,按原目录启动,不通过清库处理版本错配。
|
||||
- Router 配置缺失不应只在首次请求时报错。API/All 启动必须先校验官方地址、固定模型、provisioning secret、管理员 Token 和凭据加密密钥;否则服务看似 healthy,但登录后的 provisioning/模型调用才延迟失败。
|
||||
|
||||
@@ -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 检查。
|
||||
@@ -1617,6 +1617,7 @@ V1.51 在不替换现有 Provider、Runner 和 Runtime 事实源的前提下增
|
||||
### 配置与验收
|
||||
|
||||
- `check_game_creator_llm_config` 在 CLI 模式只检查固定 Codex 可执行文件可启动并返回受支持版本,不要求 LLM API Key;Provider 模式保持既有检查。配置 UI 显示全局模式,始终保留旧 LLM/逐 Agent/MCP/Editor 配置;切换模式不清空任何旧值。
|
||||
- Tauri 配置页触发的 `check_game_creator_llm_config` 必须通过阻塞线程池执行 Codex CLI / app-server 探测,不能在窗口线程同步等待;配置文件读写不得因诊断探测阻塞整个 GameAgent 窗口。
|
||||
- fake Codex fixture 必须覆盖 argv/stdin、structured calls、final text、非零退出、挂起取消、损坏/超限 JSONL、无 shell/MCP 参数和并发节点;真实 smoke 只复用用户已有 Codex 登录态。旧 Provider smoke 继续作为回退模式门禁,不能被新 CLI smoke 替代。
|
||||
|
||||
## V1.52 Codex app-server 长期节点 Agent 模式
|
||||
|
||||
@@ -217,7 +217,7 @@ Supervisor 认领该回执后,由父 run 自己为每个原 delivery 逐一创
|
||||
- 安装包侧车:Windows x64 release 固定随 Tauri resource 打包 `@openai/codex@0.147.0` 的原生 `codex.exe`;Rust build script 从 AGC 子包锁定依赖 stage 到 resource,并写入版本与 SHA-256 清单。Windows 侧车映射只写入 `tauri.windows.conf.json`,通用 `tauri.conf.json` 不得让 Linux / macOS 构建依赖未生成的 Windows 二进制。运行时只在文件摘要和 `codex-cli` 版本同时匹配清单时优先选内置侧车;缺失、损坏或版本漂移时跳过它,按既有 npm 安装、PATH 顺序回退。安装包同时携带 Apache-2.0 第三方声明;API Key、`auth.json`、Cookie、Token、用户 `CODEX_HOME`、用户配置和项目数据绝不打包。
|
||||
- Windows x64 release 安装包只生成 NSIS,不生成 MSI:`tauri.windows.conf.json` 的 `bundle.targets` 固定为 `["nsis"]`,通用配置继续保留其它平台的默认打包目标。
|
||||
- CLI 安全边界:CLI 固定使用 argv 启动,禁止 shell 拼接;工作目录使用本次请求专用的空临时目录,不把游戏项目绝对路径写入 prompt、stdout、stderr 或持久记录。调用固定使用 ephemeral、忽略用户配置和 exec rules、read-only sandbox、never approval,并关闭 Codex shell tool;只继承 CLI 运行和认证所需的最小环境,显式移除宿主 `CODEX_API_KEY`。用户级 Codex 登录态继续由本机 Codex 自己读取,API Key、auth 文件、Cookie、Token、`CODEX_HOME` 私有内容不得复制到项目配置、Runtime sidecar、Agent DB、conversation 或日志;stdout / stderr 无换行时也受硬上限约束,stderr 诊断只记录固定分类、字节数和 SHA-256。
|
||||
- 协议边界:Runtime 把既有 `LlmRunRequest` 的消息和当前函数目录编码为有界 prompt,并从同一函数 JSON Schema 生成 Codex structured-output schema。CLI 输出转换为现有 `LlmRunResponse / LlmToolCall` 后,继续经过 native tool / MCP 参数校验、动作上限、权限、pending、receipt、验证与格式修复链;最终回复仍走现有脱敏和唯一提交路径,不新增平行响应协议。
|
||||
- 协议边界:Runtime 把既有 `LlmRunRequest` 的消息和当前函数目录编码为有界 prompt,并从同一函数 JSON Schema 生成 Codex structured-output schema。CLI 输出转换为现有 `LlmRunResponse / LlmToolCall` 后,继续经过 native tool / MCP 参数校验、动作上限、权限、pending、receipt、验证与格式修复链;最终回复仍走唯一提交路径,不新增平行响应协议。
|
||||
- 取消与恢复:Codex 子进程绑定当前 Provider request lifecycle,取消、暂停、Runner draining 或 GUI owner 丢失时终止并回收当前进程;started 后没有可信终态仍沿现有 Provider reconciliation 处理。`agentMode`、CLI 可执行身份和影响输出的 Codex 参数进入 `providerConfigFingerprint`,模式切换不得消费另一模式遗留的 retry/handoff。
|
||||
- 可用性与兼容:`check_game_creator_llm_config` 在 `codex_cli` 模式检查 Codex 可执行文件和版本,不再要求 HTTP API Key;在 `provider` 模式保持原有 API Key、base URL、model 和逐 Agent override 校验。设置面板始终保留旧 Provider 配置,模式切回后不得丢失既有密钥或逐 Agent设置。配置向导若写入 HTTP Provider 凭据,必须显式把模式切到 `provider`。
|
||||
- 验收:覆盖缺省模式、显式 Provider 回退、配置 round-trip、CLI 缺失/非零退出/损坏 JSONL/超限输出、structured tool calls、普通最终回复、进程取消、模式指纹漂移和旧 Provider 回归;同时执行 AGC 定向 Rust 测试、前端配置测试与 typecheck、配置门禁、编码检查和 `git diff --check`。
|
||||
@@ -1198,8 +1198,8 @@ game-project/
|
||||
|
||||
- 普通项目对话只由一个 project-bound Codex app-server thread 执行。客户端系统提示词只放最小工程合同、当前游戏源码有界快照、项目 prompts 和审核 Skill 索引;不再批量读取项目 `.codex/.agents` Skill 正文,也不恢复 Supervisor、专业 Agent 或 harness。
|
||||
- 首页恢复“做游戏 / 做素材 / 做方案”三个创作类型,默认“做游戏”。该选择与设置页的 Agent Runtime 模式无关;每次首页提交仍只自动创建一个新项目并进入项目工作台。用户正文原样进入项目对话,`game|art|doc` 仅作为受限结构化首轮上下文传给同一 Codex thread,不拼接“初始意图”文案、不产生首页对话、不切换 Provider 或恢复旧 Runtime 编排。
|
||||
- `agc-skill-pack.v1` 只包含项目结构、陶泥儿美术、Web 游戏实现、真实浏览器试玩、客户端资源投影五项 Skill。清单记录用途、触发条件、所需工具、版本和内容 SHA-256;审核文本按 UTF-8 读取并将 CRLF 规范为 LF 后计算指纹和安装,避免混合换行造成 Windows / Linux 构建结果漂移,语义内容变化时必须同步重算对应清单指纹并提升版本。同步统一运行 `npm run agc:skill-pack:sync`,只读校验由 AGC `typecheck` 和 release build 自动执行,发现漂移时直接列出 Skill 与实际摘要,不让失配内容进入构建产物。客户端把审核文件安装到隔离目录后通过 app-server `skills/extraRoots/set + skills/list` 注册并复核,完整正文与 references 均由 Codex 原生 Skill 机制按意图和声明的相对路径按需读取。
|
||||
- DirectProject 始终连接客户端内置的 `agc_tools` STDIO MCP;2026-08-31 起还会在启动时接入客户端扩展仓库中用户已启用的独立第三方 STDIO/HTTP MCP 配置,但不读取用户全局 Codex MCP、不开启完整 Plugin Runtime。`agc_tools` 工具固定为标准陶泥儿美术准备、已登记资源有界查询、视频 / 角色动画 / 音效 / BGM 的 create-or-derive 语义生成、已登记图片去背景和 desktop/mobile 浏览器试玩。内置 MCP 进程只做协议;真实浏览器与付费 External v1 调用通过随机 loopback 地址回到客户端主进程,因此不复制 GUI 登录态、开发者 Key、项目路径、revision、operation 或幂等键到模型上下文。内置与用户启用的第三方 MCP 工具都沿用 DirectProject 自动批准方式,但付费资源工具仍由客户端绑定稳定回合身份、限制单回合请求数、串行执行并优先恢复匹配账本;Codex 原生 webSearch、任意原生命令网络、多 Agent 和完整插件能力继续关闭。
|
||||
- `agc-skill-pack.v1` 只包含项目结构、陶泥儿美术、Web 游戏实现、真实浏览器试玩、客户端资源投影五项 Skill。清单记录用途、触发条件、所需工具、版本和内容 SHA-256;审核文本按 UTF-8 读取并将 CRLF 规范为 LF 后计算指纹和安装,避免混合换行造成 Windows / Linux 构建结果漂移,语义内容变化时必须同步重算对应清单指纹并提升版本。同步统一运行 `npm run agc:skill-pack:sync`,只读校验由 AGC `typecheck` 和 release build 自动执行,发现漂移时直接列出 Skill 与实际摘要,不让失配内容进入构建产物。客户端把审核文件安装到隔离目录后通过 app-server `skills/extraRoots/set + skills/list` 注册并复核,完整正文由 Codex 原生 Skill 机制按意图加载,一层引用只能经 `agc_read_skill_resource` 读取清单内 Markdown。引用路径按平台无关规则拒绝反斜杠、盘符、UNC、绝对路径和 `..`,不能依赖当前宿主的 `std::path` 语义判断其它平台路径。
|
||||
- DirectProject 始终连接客户端内置的 `agc_tools` STDIO MCP;2026-08-31 起还会在启动时接入客户端扩展仓库中用户已启用的独立第三方 STDIO/HTTP MCP 配置,但不读取用户全局 Codex MCP、不开启完整 Plugin Runtime。内置工具固定为审核引用读取、标准陶泥儿美术准备、已登记资源有界查询、视频 / 角色动画 / 音效 / BGM 的 create-or-derive 语义生成、已登记图片去背景、desktop/mobile 浏览器试玩和受控 `agc_web_search`。内置 MCP 进程只做协议;真实浏览器、付费 External v1 调用与受控搜索通过随机 loopback 地址回到客户端主进程,因此不复制 GUI 登录态、开发者 Key、项目路径、revision、operation 或幂等键到模型上下文。内置与用户启用的第三方 MCP 工具都沿用 DirectProject 自动批准方式,但付费资源工具仍由客户端绑定稳定回合身份、限制单回合请求数、串行执行并优先恢复匹配账本;通用 shell、Codex 原生 webSearch、任意原生命令网络、多 Agent 和完整插件能力继续关闭。`llm.webSearchEnabled` 只控制 DirectProject 的 AGC 受控搜索工具暴露与执行,Codex 原生 `web_search` 始终保持 disabled;Provider、ToolHost、DirectHome 不纳入本次联网主链路。
|
||||
- 陶泥儿生成继续复用持久幂等账本、operation 恢复、来源/下载/PNG 解码和 manifest 登记;普通客户端优先使用当前 AGC 登录会话及账号路由,只有受控的 ExternalDeveloper 发布模式才在客户端内部使用按服务器 origin 隔离的私有 Key。用户和模型都不需要提供或配置 API Key;凭据失效、来源不明或结果未知时失败关闭,不能自动换 Key 或重新扣费。
|
||||
- 自定义 LLM API Key 路由只在 DirectHome/DirectProject 经 loopback `/responses` 流式代理转发。代理不注入 Key,只要求请求自带 Bearer,并剥离开发网关错误携带的 `X-Codex-*` ChatGPT 账户额度头,防止隔离 app-server 把 API Provider 误判为余额 0;旧 ToolHost 保持原 Provider 行为。
|
||||
|
||||
@@ -1274,3 +1274,11 @@ DirectProject 使用 `approvalPolicy=never`,避免每次原生调用再经过
|
||||
- `autonomous-game-build` 运行档位采用自主并行编排:manifest `dependencies` 仅作为上下文提示,不参与 ready 判定;代码、设计、美术、音频和发布 child 可以按调度器可用性并行启动。child 不要求固定 task ID、owner、parent-child lineage、run ID 或回执顺序,完成投影按同一项目事实幂等收束。
|
||||
- 该档位不把最终验收条件提前成启动条件,也不把平台画布、preview、static smoke、发布包或其它平台产物检查作为 child 或根 Supervisor 的完成门。缺少平台产物不会把已完成任务重置为 `Pending`;根 run 只等待任务图进入终态并交回结果。
|
||||
- 代码可先按约定的项目路径落地并完成自己的工作;后续任务状态变化只负责唤醒同一根 run 继续收束,不因 `art-polish`、`art-asset-plan` 等非代码任务失败而阻塞代码启动。平台产物和可玩性检查若需要,属于后续独立验收,不是本档位的运行前置条件。
|
||||
|
||||
## 2026-08-29 DirectProject 受控联网搜索闭环
|
||||
|
||||
- 本次正式产品范围只包含 `DirectProject` 单 Codex Agent;`Provider`、`ToolHost`、`DirectHome` 不新增联网工具桥,也不纳入本次联网路由覆盖。受控联网唯一实现为 `agc_tools.agc_web_search`:Codex app-server 通过审核的 STDIO MCP 工具目录发起调用,客户端 loopback 工具桥执行固定 Bing RSS HTTPS 请求,过滤非 HTTPS、凭据 URL、回环 / 私网 / 本地域名,返回有界标题、摘要和结果链接,并以“不可信网页内容”标签回传。
|
||||
- Codex 原生 `web_search` 在 app-server 启动参数中始终保持 `web_search=\"disabled\"`。`llm.webSearchEnabled` 在 `DirectProject` 仅表示受控工具开关,不得被状态文案解释为 Codex 原生联网;工具桥关闭时即使收到旧调用也失败关闭。原生命令网络、任意外部 MCP、工具参数透传、网页内容改写系统规则 / 身份 / 权限 / 协议均继续禁止。
|
||||
- 配置文件新增 `schemaVersion: \"game-creator-config.v2\"`。新默认配置开启 `stream` 与受控联网;无版本旧配置在启动时补写 v2,旧 `codex_app_server` 路由仅在省略 `webSearchEnabled` 时按历史默认补为开启,显式 `false` 保留;Provider / Anthropic 路由未提供搜索覆盖时保持关闭,避免继承 DirectProject 默认。主配置按完整配置迁移;本地覆盖只补 schema 版本,不凭不完整 overlay 推断或写入 `agentMode` / 搜索布尔值。
|
||||
- `/llm-status`、开发单 Agent 状态和项目 Agent 状态卡对 Codex 模式显示“流式开启 / 关闭”“受控联网开启 / 关闭”“Codex 原生 web_search 关闭”,不显示 API Key、URL、请求头、绝对路径或 Provider 原始错误正文。
|
||||
- BDD 验收场景与测试映射:DirectProject 默认工具目录包含 `agc_web_search` 且原生搜索仍 disabled;未审核字段、越界数量和非公开 URL 在桥接端失败关闭;旧无版本配置迁移为 v2 且按路由得到正确默认;状态卡显示三态安全摘要。对应 Rust `configuration`、`direct_tools_mcp`、`direct_tool_bridge`、`codex_app_server` 定向测试及前端状态格式化 / AppSurface 测试。
|
||||
|
||||
@@ -291,7 +291,7 @@ chat_with_game_creator_direct_codex
|
||||
|
||||
`direct_game_creator_codex_chat_at_with_optional_observer` 增加可选 `audit: Option<&mut DirectCodexTurnAudit>`,再传到 `run_turn_with_direct_observer`。仅 `workspace_mode == DirectProject` 且 `audit` 为 Some 时抽取。
|
||||
|
||||
`run_direct_game_creator_turn_inner` 的 UI observer 保持只处理 `AccumulatedText` / `Activity`。
|
||||
`run_direct_game_creator_turn_inner` 的 UI observer 把 `AccumulatedText`(仅开启流式时)映射为 `streaming`,`IntermediateText` 与 `Activity` 一律映射为 `running`,只向前端暴露安全活动词与可见正文,不携带原始 item JSON。
|
||||
|
||||
回合失败(生成失败、浏览器试玩失败、回复落盘失败):只要 `start` 过就 `finish(false)`,保留已观察到的 item。Codex 尚未启动则 `itemCount=0`。
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# LLM 累计额度结算
|
||||
|
||||
## 目标与边界
|
||||
|
||||
使用 New API `GET /api/user/{id}` 的 `used_quota` 累计值结算,不按 token 估价,不依赖单次响应 cost,不建立本地 WAL、余数 Map 或延迟队列。模型调用前同步并检查余额,成功响应后再同步;失败、断流或进程退出留下的消耗由下一次调用前同步补结算。不承诺无后续调用的闲置账号立即结清。
|
||||
|
||||
## 单位与算法
|
||||
|
||||
Router `GET /api/status` 的 `data.quota_per_unit` 已实测为 500000,即每美元 500000 quota。美元数值直接乘 10 转泥点,不使用 USDExchangeRate。每泥点对应 50000 quota,采用整数运算。查询时验证单位不变,异常时拒绝结算,不静默改价。
|
||||
|
||||
```text
|
||||
pending = max(observed_used_quota - settled_quota, 0)
|
||||
charged_points = min(pending / 50000, spendable_points)
|
||||
next_settled_quota = settled_quota + charged_points * 50000
|
||||
```
|
||||
|
||||
`settled_quota` 只推进实际扣费对应的部分。查询失败、钱包被冻结、扣款失败时不推进。重复或乱序快照不回退游标;Router 重置累计值需人工核对,不自动清零本地记录。
|
||||
|
||||
## 持久化与事务
|
||||
|
||||
新增私有表 `llm_router_billing_checkpoint`,主键沿用已认证用户的 `llm_router_account.account_key`,保存 `router_user_id`、`settled_quota` 和更新时间。账号 owner/route 来自现有本地映射,不信任客户端提交的 Router ID;同一映射更换 Router ID 时拒绝结算,需明确迁移。
|
||||
|
||||
首次同步在模型请求之前执行:若没有 checkpoint,以当前累计额度完整建立基线,不扣历史,不抹零。现有账号与首次接入账号均在使用前建立基线。
|
||||
|
||||
只有服务身份可以调用结算 procedure。事务内先检查人工冻结与退款欠款限制(包括尚不足一整点与首次初始化),再读取 checkpoint,计算可扣金额,更新钱包和流水,最后推进 checkpoint;三者同一事务提交。返回的剩余可消费余额扣除了退款占用与本次消费,模型调用前据此拒绝零可用余额。并发、重复快照和响应丢失后重试不能重复扣费。流水 ID 由账号与已结算额度区间构成,而非单次请求 ID。
|
||||
|
||||
新增流水来源 `llm_router_consume`,显示“LLM 调用消耗”,保持免费/会员/永久泥点消耗顺序、退款冻结和消费统计。历史资产来源流水不改写;旧资产生成扣费/退款协议不变。
|
||||
|
||||
## 验收
|
||||
|
||||
- 首次基线、234 余量跨次保留、重复/乱序快照、余额不足、零余额、整数溢出均有定向测试。
|
||||
- Router 查询验证业务 success、用户 ID、非负整数 used_quota、quota_per_unit;错误不打印凭据或原始用户数据。
|
||||
- 模型请求前基线失败关闭;成功模型响应不因后置同步故障变为失败,下一次可重试。
|
||||
- schema 同步 migration、表目录、生成绑定,运行定向 Rust 测试、schema guard、编码检查、diff check。
|
||||
- 本次不部署、不迁移历史钱包流水、不修改外部 OpenAPI。
|
||||
@@ -631,8 +631,37 @@ Responses 的终态载荷既是工具调用的恢复源,也是正文的恢复
|
||||
|
||||
- Rust 结构体:`ExternalApiKey`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/external_api_key_storage.rs`
|
||||
- 说明:外部 OpenAPI 调用使用的账号级 API Key 凭据表,只保存 key prefix、SHA-256 hash、作用域、撤销状态和使用时间;明文 Key 只在 `/api/profile/api-keys` 创建接口返回一次,不进入 SpacetimeDB,且 API Key 管理接口不写入外部 OpenAPI JSON。v1 默认作用域为 `editor:project`、`editor:canvas`、`editor:image-generate`、`editor:asset`;其中 `editor:project` 覆盖项目列表、最近项目、创建、读取、重命名和删除,`editor:canvas` 覆盖默认画布布局保存,`editor:image-generate` 覆盖编辑器现有图片生成、重绘 / 调整、去背景、规范图、宣发素材、图标 spritesheet 生成 / 拆分、UI 设计图素材拆分、角色动画、视频、音效和背景音乐生成,`editor:asset` 覆盖素材直传凭证、素材对象确认、签名读取、账号级素材库和项目画布资源记录操作。
|
||||
- 说明:本表只承载普通外部 OpenAPI/MCP API Key。明文只在 `/api/profile/api-keys` 创建接口返回一次,服务端保存 `key_hash`、`key_prefix`、作用域和撤销状态;本需求不向该表增加 Router 字段,也不写入 Router 账号数据。v1 默认作用域为 `editor:project`、`editor:canvas`、`editor:image-generate`、`editor:asset`。
|
||||
- 索引:`by_external_api_key_owner_user_id` 用于登录态 API Key 列表;`key_hash` 唯一索引用于外部 API 鉴权。
|
||||
- 2026-08-31 修订:Router 账号状态、API Key 核心字段、账号元数据和加密凭据统一写入 `llm_router_account`;`external_api_key` 保持普通外部 OpenAPI/MCP Key 的原有链路不变。公共 Router、独立数据库的部署必须共享同一版本 provisioning secret,数据库缺行时才能恢复同一远端账号。LLM 计费的当前权威口径是下方 2026-09-05 累计额度结算规则。
|
||||
- 2026-09-01 修订:Router provisioning 允许所有环境使用官方固定 Router 控制面,以便独立开发数据库通过完整 owner `user_id` 的稳定派生凭据和 `agc_auto_generate` Token 复用同一远端账号/Key。由于 New API 的 `username`、`password`、`display_name` 均限制 20 个字符,用户名固定为 `agc_user_` 加 11 位 URL-safe SHA-256 短码,密码为基于完整 owner `user_id` 与 provisioning secret 派生的 20 位 hex;完整 owner `user_id` 通过 New API 用户 `remark` 字段保存,并在本地 `llm_router_account.owner_user_id` 保留权威映射。非官方公网地址仍拒绝,loopback 仅用于本地 fixture。使用共享官方 Router 的非生产环境启动时告警,提醒会触及线上账号与额度。api-server 不再提供任何 fallback Key 路径;没有已完成 provisioning 的账号行时,LLM 请求必须在本地解析阶段失败关闭。
|
||||
- 2026-09-01 修订:每次账号认证、Router Key 准备或 LLM 请求解析既有账号时,api-server 都会在同一 owner 级 provisioning 锁内检查固定套餐 `plan_id=1`。没有 active 订阅、订阅已过期或 `end_time` 距当前 Unix 秒不超过 24 小时时,使用管理员接口新建一条订阅;超过 24 小时则复用现有订阅。订阅检查不进入 Responses 流式 chunk,管理员 Token 缺失时仅保留启动告警并跳过续期检查。
|
||||
- LLM Router 计费:读取 Router 用户 `used_quota`,以 `50000 quota = 1 泥点` 结算(`500000 quota = 1 USD`,美元数值直接乘 10,不乘汇率)。上游调用前建立首次基线并补结算,成功响应后同步;不足整数部分、扣费失败和余额不足未支付部分留到后续累计同步。扣钱包、写 `llm_router_consume` 流水与推进 checkpoint 在同一事务完成;流水展示“LLM 调用消耗”。历史费用不追扣。详细契约见 `technical/【技术方案】LLM累计额度结算-2026-09-05.md`。
|
||||
- 2026-09-05 修订:`/api/llm/responses` 与 `/api/llm/chat/completions` 仍在 Router provisioning 前用钱包总余额阻止零余额账号创建或续期;解析凭据后、上游调用前再执行累计额度同步,以扣除退款占用后的剩余可消费余额为准。余额为 `0` 时返回 `409 MUD_POINTS_INSUFFICIENT`;余额或额度同步失败时失败关闭。上游已成功时,后置同步失败只记录错误并留待下次调用前补结算,不把成功模型响应改写为失败。
|
||||
- Windows 私有文件准备:AGC 自有 AppData、凭据目录和 `.agent` 运行态继续使用 managed 范围;用户通过原生选择器明确选中的项目根或文件,若 owner/DACL 仅因权限不足无法读取,则由一次性 UAC helper 在严格复核普通文件/目录、非 reparse/symlink、路径类型和目标 TokenUser 后接管并收紧为当前用户私有 DACL。项目放在当前 profile 之外(例如其他磁盘)不再因为路径位置被拒绝;未经过原生选择器或 AGC 项目根入口的内部路径仍不获得任意提权资格。
|
||||
|
||||
### `llm_router_account`
|
||||
|
||||
- 当前 AGC Router 需求由 `llm_router_account` 表单独承载:API Key 核心字段、加密凭据、Router 账号元数据、生命周期与 provisioning 状态均在该表;不依赖 `external_api_key`。api-server 每次上游调用都读取权威 `llm_router_account` active/revoked 状态并即时解密当前密文,不做 TTL 凭据缓存,避免任意实例轮换或撤销后继续使用旧 Key。
|
||||
|
||||
- Rust 结构体:`LlmRouterAccount`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/llm_router_account.rs`
|
||||
- 作用:记录用户与官方 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` 用于按状态和下次重试时间扫描待对账账号。
|
||||
|
||||
### `llm_router_billing_checkpoint`
|
||||
|
||||
- Rust 结构体:`LlmRouterBillingCheckpoint`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/runtime/active/profile.rs`
|
||||
- 私有表,主键 `account_key` 关联 `llm_router_account`,保存 `router_user_id`、`settled_quota`、`updated_at`。
|
||||
- `settle_llm_router_quota_and_return` 仅允许服务身份,验证 owner/route/Router ID;首次同步完整记录当前额度而不扣历史,后续仅按实际扣款推进额度,与钱包和流水同事务提交。旧快照不回退;账号更换拒绝自动重建。
|
||||
|
||||
### `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`
|
||||
|
||||
@@ -1375,3 +1404,4 @@ RPG 创作入口的配置 ID 是 `rpg`,当前 `visible=true`、`open=true`;
|
||||
- 源码:`server-rs/crates/spacetime-module/src/legacy_schema/visual_novel.rs`
|
||||
- 说明:视觉小说公开 source 投影,只暴露 `publication_status = published` 的作品卡片字段,不把完整 `draft` 暴露给公开列表订阅;统一公开列表 / 详情主路径通过 `public_work_gallery_entry` / `public_work_detail_entry` 消费该 view 并映射成跨玩法契约。个人历史、详情、运行态和发布仍按原有 procedure / reducer 路径处理。
|
||||
- 字段变更:`visible` 控制是否进入公开列表 / 详情,新作品默认 `false`;旧迁移数据由 `migration.rs` 按历史公开默认补 `true`。
|
||||
> 2026-09-03 修订:认证成功后的 Router provisioning 改为异步尽力修复,不再阻塞主站登录;LLM 热路径只读取本地已完成的账号密钥,控制面不可用时请求失败关闭。provisioning secret 仅从部署侧受保护环境变量或 secret file 读取,不再内置源码常量。
|
||||
|
||||
@@ -213,6 +213,27 @@ SpacetimeDB procedure:
|
||||
- `revoke_external_api_key_and_return`
|
||||
- `authenticate_external_api_key_and_return`
|
||||
|
||||
### LLM Router 账号 Key 与 Router 代理
|
||||
|
||||
本次 AGC Router 需求不改造原有 `external_api_key`。Router 账号、API Key 核心字段、生命周期和加密凭据统一保存在 `llm_router_account`;明文凭据只在 api-server 进程内短暂存在,并按 owner + route 进行 10 分钟内存缓存,轮换或撤销时立即清理。
|
||||
|
||||
普通 AGC 发行版不把 Router 当作客户端可配置 Provider,也不把 Router API Key 下发到桌面端。注册成功视为账号已有可用余额;认证成功后,api-server 异步尽力准备该用户对应的 Router 账号和 API Key,Router 控制面故障不得阻塞主站登录;LLM 请求解析阶段只读取 `llm_router_account` 中合法的已完成 provisioning 凭据。当前按 New API 管理接口执行正式 provisioning:由于 `username`、`password`、`display_name` 均限制 20 个字符,用户名固定为 `agc_user_` 加 11 位 URL-safe SHA-256 短码,密码为基于完整 owner `user_id` 与部署侧受保护 provisioning secret 稳定派生的 20 位 hex,展示名与短用户名一致;完整 owner `user_id` 写入 New API 用户 `remark`,本地 `llm_router_account.owner_user_id` 仍是平台权威映射。服务端先查询远端用户:已存在则直接登录,不重复注册;确认不存在时才由管理员创建普通用户,查询用户 ID,设置 `remark=<完整 owner user_id>` 与用户分组 `taonier`,再登录、查询并复用固定标识 `agc_auto_generate` 的 Token(Token/API Key 固定使用 `default` 分组;已有固定 Token 若分组不是 `default`,登录恢复时先通过 Token 更新接口纠正),签发 API Key。每次新建或准备 API Key 时,服务端在签发前查询该 Router 用户的固定套餐 `plan_id=1`;无 active 订阅、订阅已过期或剩余时间不超过 24 小时时调用管理员订阅接口新建一条订阅,剩余超过 24 小时则复用现有订阅。订阅查询/创建只使用 api-server 私有管理员 Token,不进入客户端或 Router Key;检查锚点是显式 Router Key 准备接口和新 Key provisioning,不放在 Responses 流式 chunk 中。由于 Router 公共而各部署数据库独立,所有能操作同一 Router 的部署必须使用相同的 provisioning secret。若任一步外部结果不确定,记录进入 reconciliation 状态,禁止重复注册;本地 API Key 写入失败则保留 `key_issued` 状态并用确定的 key id 重试落库。Router 密文加密优先使用 `GENARRATIVE_LLM_ROUTER_API_KEY_ENCRYPTION_SECRET`;缺省时使用带域分离的 `GENARRATIVE_JWT_SECRET` 派生密钥。Router Key 的明文只在 api-server 进程内短暂存在;缓存命中时不访问数据库,缓存未命中时从 `llm_router_account` 解密并写入 10 分钟进程内缓存;`/api/profile/api-keys/llm-router` 只返回安全元数据;普通 External Editor Key 仍沿用创建接口明文只显示一次的正式链路。后续请求链路固定为:
|
||||
|
||||
```text
|
||||
AGC loopback Provider Proxy(Bearer=平台 access token)
|
||||
-> POST /api/llm/responses
|
||||
-> api-server 从 access token 得到 userId,查询并解密 llm_router_account
|
||||
-> POST https://router.genarrative.world/v1/responses(Bearer=<router-api-key>)
|
||||
```
|
||||
|
||||
`/api/llm/responses` 透传 Responses JSON/SSE 响应;模型由当前 AGC 模型目录解析。计费读取 Router 子账号的累计 `used_quota`,按 `50000 quota = 1 泥点` 在调用前后同步;首次同步只建立历史基线,扣钱包、写 `llm_router_consume` 流水与推进 checkpoint 在同一事务完成。Router 明确返回 `401/403` 时,服务端将该用途 Key 标记撤销;网络超时或 provisioning 未取得确定响应时不自动重试。客户端不保存 Router Key,也不把它放进 argv、环境变量、manifest、trace、聊天或普通 IPC。AGC 的运行状态接口与 `/llm-status`、`/llm-routes` 只返回登录/账号凭据状态、官方路由锁定状态和运行参数,不返回 Router 地址、模型、协议名称或任何凭据字段。
|
||||
|
||||
Windows 私有路径由同一套正式准备入口复用:AGC 自有 AppData、凭据目录和 `.agent` 运行态使用 managed 范围;原生文件选择器明确选中的项目根/文件使用 user-selected 范围。两类入口在发现 owner/DACL 权限不足时均允许一次性 UAC helper;helper 只接管严格复核后的普通文件/目录,并写入当前 TokenUser owner、禁止继承且仅含当前用户 ACE 的 DACL。reparse/symlink、非普通对象、祖先类型冲突和未经过正式选择/项目根入口的路径仍失败关闭。
|
||||
|
||||
管理员 Token 仅由 api-server 私有配置 `GENARRATIVE_LLM_ROUTER_ADMIN_TOKEN` 或对应文件提供,不进入客户端、数据库、日志或请求 payload。当前仓库无法验证真实管理员 Token、真实账号 Key 与生产 Router `/v1/responses` 联通;这些仍需在受控部署 smoke 中完成,客户端不得退回手工 Key。
|
||||
|
||||
运行环境隔离是 provisioning 的前置门禁:所有环境都允许使用官方固定 Router 地址,开发环境因此可以通过完整 owner `user_id` 派生的稳定短用户名、稳定密码和 `agc_auto_generate` Token 复用共享 Router 账号;完整 owner `user_id` 同步写入 New API 用户 `remark`,便于 Router 侧统计回溯平台账号。非官方公网地址仍被拒绝,loopback 地址仅用于本地 fixture。使用共享官方 Router 的开发环境会实际创建/使用线上账号与额度,启动时必须告警。测试代码也不再通过进程级 fallback Key 旁路数据库;只有显式、按 owner 绑定的“已完成 provisioning” fixture 才能模拟已有账号,未提供 fixture 时必须经过 `llm_router_account` 读取或正式 provisioning,不能访问 Router。数据库记录缺失时,稳定短用户名/密码先尝试恢复远端账号;只有确认远端不存在才注册,避免跨部署数据库为空时重复创建用户。
|
||||
|
||||
## 素材生成与落库
|
||||
|
||||
外部生成接口复用站内编辑器已有 DTO、入队器和 worker executor,不维护第二套生成语义:
|
||||
@@ -272,3 +293,4 @@ docs/openapi/genarrative-external-v1.openapi.json
|
||||
- 外部项目接口覆盖当前已有项目管理操作:项目列表、最近项目、创建、读取、重命名、删除和默认画布保存。
|
||||
- 外部素材生成接口覆盖当前已有编辑器素材操作:生图、重绘 / 调整、规范图生成、宣发素材生成、图标素材生成与拆分、UI 设计图生成与拆分、角色动画、视频、音效和背景音乐。
|
||||
- 修改 SpacetimeDB schema 后运行 `npm run spacetime:generate` 与 `npm run check:spacetime-schema`。
|
||||
> 2026-09-05 修订:认证成功后的 Router provisioning 为异步尽力修复,不阻塞主站登录;LLM 请求只使用本地已完成的账号密钥。LLM Router 计费改为累计 `used_quota` checkpoint 结算,不再依赖单次响应 usage、客户端幂等键或请求指纹;账号密码派生根仅从部署侧受保护 secret/file 读取。
|
||||
|
||||
@@ -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
|
||||
@@ -960,3 +964,4 @@ node scripts/rebind-orphan-work-owners.mjs --in <exported-migration.json> --out
|
||||
## 维护页目标文件安全边界(2026-08-05)
|
||||
|
||||
`scripts/deploy/maintenance-on.sh` 只允许把同目录临时普通文件原子替换到普通文件或尚不存在的 `page.html` / `enabled` 目标。目标只要是符号链接(包括指向目录的链接)或目录,脚本必须在替换前失败,不能跟随链接把临时文件移入链接目标,也不能打印“已进入维护模式”。`page_temp` 与 `marker_temp` 必须在 `set -u` 下安全初始化,清理 trap 必须在首次 `mktemp` 前生效;任一失败退出都不得在目标同级遗留 `page.html.tmp.*` 或 `enabled.tmp.*`,成功替换后则清空临时路径并解除 trap,不能误删已安装目标。跨平台实现继续使用 POSIX `mv -f`,安全语义由替换函数的目标类型门禁保证;修改后运行 `bash -n scripts/deploy/maintenance-on.sh` 与 `npm run check:maintenance-page`。
|
||||
api-server 启动时会硬校验 AGC 官方 Router 配置:API/All 角色必须使用官方 HTTPS 地址和固定模型,并配置 provisioning secret、Router 管理员 Token,以及专用加密 secret 或有效 JWT secret;缺失或不匹配直接拒绝启动。`test` 环境仅允许 loopback fixture,worker-only 角色不执行 Router 配置校验。
|
||||
|
||||
Reference in New Issue
Block a user