优化AGC客户端同步LLM配置 #306

Merged
suzmii merged 5 commits from feat/agc-client-sync-llm-config into master 2026-09-09 13:19:44 +08:00
Member

背景

后台在「AGC 模型」页发布新配置后,客户端必须手动刷新(或重启)才能看到最新目录:GET /api/llm/models 只返回 modelsdefaultModelId,缺少可比较的版本标识;客户端只在组件挂载或手动点「刷新模型列表」时拉取。本 PR 按 Issue #292 的方案 A 落地「revision 契约 + 条件刷新」。

Closes #292

改动内容

后端

  • shared-contractsLlmModelsResponse 增加 revision
  • api-serverpublic_model_catalog 透出 revision,过滤与脱敏语义不变(仍不返回实际模型名)。
  • 定向单测断言 revision 透传,且响应不含 gpt- 实际模型名。

AGC 客户端

  • clientApiloadClientLlmModels 返回类型补 revision
  • 新增 services/llmModelCatalog.ts:目录缓存 + 在途请求去重(同一时刻只发一个请求,重复触发复用同一结果),失败保留上一次成功目录。
  • ConversationModelSelect:项目切换 / 表面挂载 / 下拉展开 / 窗口聚焦条件刷新,revision 未变不更新界面;停用或删除的所选模型回退默认并提示;刷新失败不清空有效选择;刷新结果不覆盖刚完成的选择、也不清除保存失败提示。
  • ProjectSupervisorView:提交前用同一份目录快照再校验一次,失效则回退默认后继续发送,默认也不可用才拦截。
  • 客户端配置新增 selectedModelIsDefault:当前选择是否来自平台默认项。后台默认项变化时,跟随默认项的选择自动切换并提示;用户手动选择后不再被默认项变化覆盖;所选模型失效回退默认时重新标记为默认项。

验证

  • npm run test -- apps/ai-game-creator-shell/tests/conversationModelSelect.test.tsx → 9/9
  • npm run test -- apps/ai-game-creator-shell/tests/appSurface.test.ts → 384/384
  • npm run ai-game-creator-shell:typecheck 通过
  • cargo test --manifest-path server-rs/Cargo.toml -p api-server model_catalog_tests → 1/1
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml model_selection_default_flag_round_trips → 1/1(src-tauri 全量测试通过)
  • npm run check:rustfmtnpm run check:encoding(4326 文件)、git diff --check、prettier/eslint 定向检查通过

影响范围与注意事项

  • /api/llm/models 仅新增 revision,兼容新增;客户端配置仅新增可选字段 selectedModelIsDefault,旧配置缺省按「非默认项」处理。未触及 /api/external/v1,无需改 OpenAPI。
  • 与 PR #299 改同一组件:本分支从 master 起,等 #299 合并后 merge master 并复用其默认回退逻辑,冲突按「保留双方行为」处理。
  • 未做真机视觉验证(仅新增回退/跟随提示文案的样式);CI 见最新提交。
### 背景 后台在「AGC 模型」页发布新配置后,客户端必须手动刷新(或重启)才能看到最新目录:`GET /api/llm/models` 只返回 `models` 与 `defaultModelId`,缺少可比较的版本标识;客户端只在组件挂载或手动点「刷新模型列表」时拉取。本 PR 按 Issue #292 的方案 A 落地「revision 契约 + 条件刷新」。 Closes #292 ### 改动内容 **后端** - `shared-contracts`:`LlmModelsResponse` 增加 `revision`。 - `api-server`:`public_model_catalog` 透出 `revision`,过滤与脱敏语义不变(仍不返回实际模型名)。 - 定向单测断言 revision 透传,且响应不含 `gpt-` 实际模型名。 **AGC 客户端** - `clientApi`:`loadClientLlmModels` 返回类型补 `revision`。 - 新增 `services/llmModelCatalog.ts`:目录缓存 + 在途请求去重(同一时刻只发一个请求,重复触发复用同一结果),失败保留上一次成功目录。 - `ConversationModelSelect`:项目切换 / 表面挂载 / 下拉展开 / 窗口聚焦条件刷新,revision 未变不更新界面;停用或删除的所选模型回退默认并提示;刷新失败不清空有效选择;刷新结果不覆盖刚完成的选择、也不清除保存失败提示。 - `ProjectSupervisorView`:提交前用同一份目录快照再校验一次,失效则回退默认后继续发送,默认也不可用才拦截。 - 客户端配置新增 `selectedModelIsDefault`:当前选择是否来自平台默认项。后台默认项变化时,跟随默认项的选择自动切换并提示;用户手动选择后不再被默认项变化覆盖;所选模型失效回退默认时重新标记为默认项。 ### 验证 - `npm run test -- apps/ai-game-creator-shell/tests/conversationModelSelect.test.tsx` → 9/9 - `npm run test -- apps/ai-game-creator-shell/tests/appSurface.test.ts` → 384/384 - `npm run ai-game-creator-shell:typecheck` 通过 - `cargo test --manifest-path server-rs/Cargo.toml -p api-server model_catalog_tests` → 1/1 - `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml model_selection_default_flag_round_trips` → 1/1(src-tauri 全量测试通过) - `npm run check:rustfmt`、`npm run check:encoding`(4326 文件)、`git diff --check`、prettier/eslint 定向检查通过 ### 影响范围与注意事项 - `/api/llm/models` 仅新增 `revision`,兼容新增;客户端配置仅新增可选字段 `selectedModelIsDefault`,旧配置缺省按「非默认项」处理。未触及 `/api/external/v1`,无需改 OpenAPI。 - 与 PR #299 改同一组件:本分支从 master 起,等 #299 合并后 merge master 并复用其默认回退逻辑,冲突按「保留双方行为」处理。 - 未做真机视觉验证(仅新增回退/跟随提示文案的样式);CI 见最新提交。
suzmii added 1 commit 2026-09-08 16:24:59 +08:00
优化AGC客户端同步LLM配置
Project CI / Frontend tests (pull_request) Successful in 3m54s
Project CI / Repository checks (pull_request) Successful in 5m41s
Project CI / Backend tests (pull_request) Successful in 14m56s
Project CI / Native shell tests (pull_request) Failing after 15m10s
d60c4ce6ec
- GET /api/llm/models 增加目录 revision,客户端据此做条件刷新
- AGC 客户端在项目切换、对话表面挂载、下拉展开、窗口聚焦时按 revision 条件刷新
- 模型目录请求同一时刻只保留一个在途请求,刷新失败保留上一次有效目录与本地选择
- 发起对话前校验所选模型,已停用或删除时回退默认模型并提示
- 新增模型目录缓存模块与定向测试,同步技术方案与后端架构文档
suzmii added 1 commit 2026-09-08 16:38:42 +08:00
修复AGC客户端未跟随服务端默认模型
Project CI / Native shell tests (pull_request) Failing after 14m52s
Project CI / Repository checks (pull_request) Successful in 5m51s
Project CI / Frontend tests (pull_request) Successful in 6m17s
Project CI / Backend tests (pull_request) Successful in 23m19s
4fc9451492
- 客户端配置新增 selectedModelIsDefault,记录当前选择是否来自平台默认项
- 服务端默认项变化时,跟随默认项的选择自动切换并提示,手动选择不受影响
- 所选模型失效回退默认项时标记为默认项选择
- 补充配置读写与客户端定向测试,同步技术方案文档
suzmii requested review from kdletters 2026-09-08 16:38:53 +08:00
suzmii marked the pull request as ready for review 2026-09-08 16:38:54 +08:00
suzmii added 1 commit 2026-09-09 10:04:29 +08:00
Merge remote-tracking branch 'origin/master' into feat/agc-client-sync-llm-config
Project CI / Repository checks (pull_request) Successful in 2m49s
Project CI / Frontend tests (pull_request) Successful in 3m26s
Project CI / Native shell tests (pull_request) Failing after 4m12s
Project CI / Backend tests (pull_request) Failing after 4m13s
2942489575
# Conflicts:
#	apps/ai-game-creator-shell/src/features/project-workspace/ConversationModelSelect.tsx
#	apps/ai-game-creator-shell/src/features/project-workspace/ProjectSupervisorView.tsx
#	apps/ai-game-creator-shell/tests/conversationModelSelect.test.tsx
#	docs/technical/【技术方案】AGC后台模型别名与对话选择-2026-09-05.md
suzmii removed review request for kdletters 2026-09-09 11:38:50 +08:00
suzmii added 1 commit 2026-09-09 12:00:32 +08:00
修复AGC模型目录同步的加载态与保存竞态
Project CI / Repository checks (pull_request) Successful in 2m56s
Project CI / Frontend tests (pull_request) Successful in 3m45s
Project CI / Backend tests (pull_request) Failing after 4m34s
Project CI / Native shell tests (pull_request) Failing after 7m54s
07fc26953a
- ConversationModelSelect:目录同步与配置读取/写回失败时统一在 finally 收起加载态,避免选择器永久卡在 busy、无法切换或刷新
- ConversationModelSelect:配置读取失败单独提示「读取客户端配置失败」,不再误报为模型目录加载失败
- ConversationModelSelect:配置写回串行化,发送前校验等待在途保存并读取最新配置,避免保存中放行旧选择、或用旧快照覆盖刚完成的选择
- ConversationModelSelect:服务端未返回 revision 时按目录已变化处理,避免界面停止刷新
- ProjectSupervisorView:提交前模型校验期间禁用输入框与发送按钮,避免重复提交与校验窗口内编辑丢失
- 测试:补充配置读取失败恢复、保存中发送前校验等待、目录请求去重用例;修正依赖配置读取时序的 appSurface 用例
- 文档:修正首页入口「按需加载」与实现不符的描述
Owner

复核结论:未发现可确认的缺陷或回归。

[P2] ConversationModelSelect.tsx 当前同时承载目录刷新、配置恢复、选择保存、默认跟随和失效回退,职责较多。建议后续考虑拆分局部 hook 或服务逻辑,降低维护复杂度。

[P3] 可补充客户端对异常 revision 响应(缺失、非法或回退值)的测试覆盖,明确缓存与刷新行为。

> 复核结论:未发现可确认的缺陷或回归。 > > **[P2]** `ConversationModelSelect.tsx` 当前同时承载目录刷新、配置恢复、选择保存、默认跟随和失效回退,职责较多。建议后续考虑拆分局部 hook 或服务逻辑,降低维护复杂度。 > > **[P3]** 可补充客户端对异常 `revision` 响应(缺失、非法或回退值)的测试覆盖,明确缓存与刷新行为。
suzmii added 1 commit 2026-09-09 13:03:59 +08:00
补充AGC模型目录异常revision的客户端用例
Project CI / Frontend tests (pull_request) Successful in 4m3s
Project CI / Repository checks (pull_request) Successful in 5m35s
Project CI / Backend tests (pull_request) Successful in 8m10s
Project CI / Native shell tests (pull_request) Failing after 17m32s
d9c883675d
- 补充旧服务端不返回 revision(两次响应均为 undefined)时仍按目录变化刷新的用例
- 补充服务端目录重建导致 revision 回退(7 到 0)时仍更新界面的用例
- 补充 revision 未变化时不更新界面、沿用已应用目录的用例
Author
Member

@lhk229 已按复核意见补齐 P3 的异常 revision 用例(d9c883675):

  • 旧服务端不返回 revision(两次响应均为 undefined、目录已变化):仍按已变化刷新,窗口聚焦后界面更新
  • 服务端目录重建导致 revision 回退(7→0):仍更新
  • revision 未变化(1→1、目录内容变化):不更新界面,沿用已应用目录

P2 的职责拆分不在本 PR 处理,已记为后续项(抽 useLlmModelCatalogSelection hook,或把目录/选择状态机下沉到 services/llmModelCatalog.ts),避免在已复核的 PR 里做结构性重构。

本地验证:conversationModelSelect 19/19、appSurface 386/386、AGC typecheck、prettier/eslint、check:encoding、git diff --check 通过。CI 的 Backend tests / Native shell tests 仍停在 runner 拉 crates.io 依赖失败(CONNECT tunnel 502),非代码问题。

@lhk229 已按复核意见补齐 P3 的异常 revision 用例(d9c883675): - 旧服务端不返回 revision(两次响应均为 undefined、目录已变化):仍按已变化刷新,窗口聚焦后界面更新 - 服务端目录重建导致 revision 回退(7→0):仍更新 - revision 未变化(1→1、目录内容变化):不更新界面,沿用已应用目录 P2 的职责拆分不在本 PR 处理,已记为后续项(抽 useLlmModelCatalogSelection hook,或把目录/选择状态机下沉到 services/llmModelCatalog.ts),避免在已复核的 PR 里做结构性重构。 本地验证:conversationModelSelect 19/19、appSurface 386/386、AGC typecheck、prettier/eslint、check:encoding、git diff --check 通过。CI 的 Backend tests / Native shell tests 仍停在 runner 拉 crates.io 依赖失败(CONNECT tunnel 502),非代码问题。
suzmii merged commit 672d93015c into master 2026-09-09 13:19:44 +08:00
suzmii deleted branch feat/agc-client-sync-llm-config 2026-09-09 13:19:44 +08:00
Sign in to join this conversation.