docs(会员): 记录模型权限改走只读 procedure 的落地状态
- 技术设计 §11.4:api-server 改调 get_profile_agc_model_access_and_return,性能说明去掉 TODO 并登记提交 - decision-log 追加「模型权限改走只读 procedure(性能收口)」条目
This commit is contained in:
@@ -9652,6 +9652,13 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
|
||||
- 影响范围:`docs/adr/【ADR】模型权限与并发上限的强制边界-2026-10-03.md`(修订节)、技术设计 §11.2/§11.4、`docs/technical/【技术方案】AGC后台模型别名与对话选择-2026-09-05.md`、`docs/project-memory/plans/【里程碑】AGC模型目录上游同步-2026-09-24.md`、本文件。
|
||||
- 验证:`npm run check:encoding`、`npm run check:doc-index`、`git diff --check`。
|
||||
|
||||
## 2026-10-03 模型权限改走只读 procedure(性能收口)
|
||||
|
||||
- 背景:`api-server` 的 AGC 模型权限解析原复用 `get_profile_recharge_center`,它带幂等的账期 / 免费点刷新与钱包 / 商品等无关快照字段,位于每个 `/api/llm/*` 请求热路径;同日「落地实现」条目已把它列为 TODO。
|
||||
- 决策:新增只读 procedure `get_profile_agc_model_access_and_return`(输入沿用 `RuntimeProfileMembershipGetInput`,结果 `RuntimeProfileAgcModelAccessSnapshot { user_id, plan, model_access }`,仅 editor generation runtime service identity 可调):只读会员账期投影 + `profile_membership_plan.model_access`,缺会员行 / 已过期按 `Normal`,缺档位目录行失败关闭到 `Basic`,不刷新、不写库;`api-server` 改调它,失败关闭语义不变。
|
||||
- 影响范围:`module-runtime`(领域类型 `9e397fe9c`)、`spacetime-module`(procedure,同提交)、生成绑定、`spacetime-client`(`get_profile_agc_model_access`)、`api-server/src/llm/model_access.rs`(`b0dc94b46`)、技术设计 §11.4。
|
||||
- 验证:`cargo check -p spacetime-module`、`cargo check -p spacetime-client`、`cargo check -p api-server --tests`;`cargo test -p api-server llm` 51 passed;`npm run check:encoding`、`git diff --check`;`npm run check:spacetime-schema` 失败项仍为分支既有 `profile_membership` / `profile_recharge_product_config` 表字段变更,与本次仅新增 procedure、未改表无关。
|
||||
|
||||
## 2026-10-03 会员链路错误分类改为机器可读错误码(typed error)
|
||||
|
||||
- 背景:`api-server/src/runtime_profile.rs` 的 `is_runtime_profile_membership_domain_error` 用中文 `error_message` 前缀 / 精确匹配决定返回 400 还是 502;文案一改(或新增拒绝点)就静默退化,且分类逻辑与 module 的错误文案跨层重复。
|
||||
|
||||
@@ -606,13 +606,13 @@ flowchart TD
|
||||
- `AgcModel` 末位追加 `#[serde(default)] access: AgcModelAccess`(存量目录 JSON 缺字段即 `Basic`,失败开放);`AgcModelCatalog` 新增 `available_models_for(access)`、`default_model_id_for(access)`、`resolve_requested_for(requested, access)`。
|
||||
- **默认模型语义**:优先取目录登记的 `default_model_id`;当它不在该档可用集合里时,回退到目录顺序里第一个可用项;该档一个可用模型都没有时返回 `Unavailable`。
|
||||
- **`spacetime-module`**:`external_generation_job` 追加 btree 索引 `(owner_user_id, status)`(`by_external_generation_job_owner_status`);`claim_external_generation_jobs_tx` 按账号解析 `concurrent_job_limit` 并在认领时过滤;上限解析走 `profile_membership.plan` → `profile_membership_plan.concurrent_job_limit`,缺会员行 / 缺目录行失败关闭到 `Normal`(=1)。
|
||||
- **`api-server`**:新增 `llm/model_access.rs`,用现有 `get_profile_recharge_center` 读出账号 `membership.plan` 与目录行 `model_access` 并映射到 `AgcModelAccess`;`GET /api/llm/models` 按档过滤,`/api/llm/responses`、`/api/llm/chat/completions`、`/api/llm/anthropic/*` 全部按档解析,越权返回 403 + 错误码 `MODEL_NOT_AVAILABLE_FOR_PLAN`。
|
||||
- **`api-server`**:新增 `llm/model_access.rs`,调专用只读 procedure `get_profile_agc_model_access_and_return`(只读会员账期投影 + 档位目录 `model_access`,不刷新、不写库)并映射到 `AgcModelAccess`;`GET /api/llm/models` 按档过滤,`/api/llm/responses`、`/api/llm/chat/completions`、`/api/llm/anthropic/*` 全部按档解析,越权返回 403 + 错误码 `MODEL_NOT_AVAILABLE_FOR_PLAN`。
|
||||
- **后台**:`AdminAgcModel` 与后台「AGC 模型」页新增 `access` 字段(`basic` / `full`,缺省 `basic`),GET 回读、PUT 写入;**不做**自动播种或代码内清单。
|
||||
- **性能说明**:本期账号档位复用现有 `get_profile_recharge_center` 读模型,它带幂等的周期刷新写入;后续可替换为更轻的专用读(TODO)。
|
||||
- **性能说明(2026-10-03 已落地)**:账号档位走专用只读 procedure `get_profile_agc_model_access_and_return`(`9e397fe9c`),不再触发 `get_profile_recharge_center` 的账期 / 免费点刷新;`api-server` 于 `b0dc94b46` 切到该读。认领按账号折叠并发查询见 `c3c3fc5a2`。缺会员行 / 已过期按 `Normal`,缺档位目录行失败关闭到 `Basic`。
|
||||
- **列表契约(2026-10-03 修订)**:`shared-contracts` 新增 `llm_catalog.rs` 承载 `LlmModelsResponse` / `LlmModelSummary` / `LlmUnavailableModel` / `LlmModelUnavailableReason`(`plan_required` / `disabled` / `unknown`);`AgcAgentMode` / `AgcModelProtocol` 从 `module-runtime` 迁入 `shared-contracts` 并由 `module-runtime` re-export;整个目录 DTO 与枚举用 `#[cfg_attr(feature = "ts-bindings", derive(ts_rs::TS))]` 导出到 `packages/shared/src/contracts/generated/`,`revision` 标 `#[ts(as = "f64")]`,AGC 前端从 `@genarrative/shared` 根导入,删掉手写的 `ClientLlmModel`。
|
||||
- **分桶来源**:`module-runtime` 新增 `AgcModelCatalog::unavailable_models_for(access)`(保持目录顺序,返回 `(&AgcModel, LlmModelUnavailableReason)`),`api-server` 只做 DTO 映射;`models` 仍走 `available_models_for`;`unavailableModels` 恒定下发(无内容时为空数组)。
|
||||
- **客户端**:AGC 桌面选择器把 `unavailableModels` 渲染为不可点项,hover / 键盘 focus 出 tooltip(`plan_required` → 「订阅计划不支持」、`disabled` → 「该模型已下线」、`unknown` → 「暂不可用」);降级仍自动回退默认,提示按 `reason` 取;后台直接删除(两桶都没有)用泛化文案「所选模型已不可用,已切回默认模型」。
|
||||
- **落地状态(2026-10-03)**:`module-runtime` 权限档与目录解析 `da9602839`;`spacetime-module` 并发索引与认领过滤 `df7682816`;后台 `access` 标注与页面 `54b02e228`;`api-server` 按档过滤 / 校验 `3aae77bc5`;认领按账号折叠并发查询 `c3c3fc5a2`。AGC 客户端侧原以「目录按档过滤 + 本地选择对账回退默认项」为主,本次修订为可用 / 不可用分桶。
|
||||
- **落地状态(2026-10-03)**:`module-runtime` 权限档与目录解析 `da9602839`;`spacetime-module` 并发索引与认领过滤 `df7682816`;后台 `access` 标注与页面 `54b02e228`;`api-server` 按档过滤 / 校验 `3aae77bc5`;认领按账号折叠并发查询 `c3c3fc5a2`。AGC 客户端侧原以「目录按档过滤 + 本地选择对账回退默认项」为主,本次修订为可用 / 不可用分桶。账号 AGC 模型权限改走只读 procedure `9e397fe9c`,`api-server` 切读 `b0dc94b46`。
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user