Skip to content

Fix/model catalog cleanup#299

Open
YQYANG2233 wants to merge 2 commits into
qxcnm:mainfrom
YQYANG2233:fix/model-catalog-cleanup
Open

Fix/model catalog cleanup#299
YQYANG2233 wants to merge 2 commits into
qxcnm:mainfrom
YQYANG2233:fix/model-catalog-cleanup

Conversation

@YQYANG2233
Copy link
Copy Markdown

@YQYANG2233 YQYANG2233 commented Jun 3, 2026

变更摘要

  • 修复 gpt-image-2 被当作普通模型目录项残留的问题,避免 Web 模型目录和 /v1/models 出现无法删除的内部图片工具模型。
  • 新增“清理远端旧模型”动作,用于显式清理不再出现在最新远端目录中的旧远端模型。
  • 删除模型时同步清理模型组引用与来源路由,避免残留映射继续影响可见模型或可调用模型。

改动范围

  • 模型 catalog 的读写、归一化、远端合并和显式清理逻辑。
  • 默认模型组和模型来源映射中的残留模型引用清理。
  • /v1/models 本地模型响应不再补入 gpt-image-2
  • 模型管理页新增远端旧模型清理按钮,并接入对应 RPC 和前端调用。

行为说明

  • “清理远端旧模型”只删除未本地覆写、非自定义、且最新远端目录已不存在的远端模型。
  • 自定义模型不会被清理。
  • 本地覆写模型不会被清理。
  • gpt-image-2 会被排除在普通平台模型目录之外。

验证

  • cargo test -p codexmanager-service apikey::models::tests
  • cargo test -p codexmanager-service gateway::local_models::tests
  • cargo test -p codexmanager-service wallet_charge_uses_model_group_billing_model_override
  • corepack pnpm test:runtime
  • corepack pnpm build
  • git diff --check

已知情况

  • corepack pnpm lint 当前仍会因为仓库已有 React hook lint 问题失败,失败点不在本次修改范围内。

风险与影响面

  • 影响模型管理页、模型 catalog 存储、默认模型组、模型来源映射和 /v1/models 输出。
  • 显式清理只作用于未本地覆写的远端旧模型,不影响自定义模型。

备注

  • 本 PR 只处理 CodexManager 自身的 Web/DB/API 模型目录一致性问题。
  • Codex CLI 自带 bundled model catalog 的显示问题需要通过本地 model_catalog_json 配置处理,不属于本 PR 范围。

Copilot AI review requested due to automatic review settings June 3, 2026 09:55
@YQYANG2233 YQYANG2233 marked this pull request as draft June 3, 2026 09:56
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR introduces a “prune stale remote models” action for the managed model catalog, and removes the implicit Codex image tool model from both API/UI listings while cleaning up legacy storage entries.

Changes:

  • Add a new RPC/UI action to prune unedited remote catalog entries that no longer exist in the remote catalog.
  • Stop injecting the Codex image tool model into model lists; filter/purge it from catalog storage and normalization paths.
  • Add storage-level cleanup helpers to remove model-group and routing references when catalog entries are deleted.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
crates/service/src/rpc_dispatch/mod.rs Allowlists the new prune RPC method.
crates/service/src/rpc_dispatch/apikey.rs Dispatches the new prune RPC method and returns filtered results.
crates/service/src/model_groups.rs Triggers catalog read/purge and prunes default model-group entries during access checks.
crates/service/src/gateway/request/tests/local_models_tests.rs Updates expectations now that the implicit image tool model is no longer injected.
crates/service/src/gateway/request/local_models.rs Removes implicit image tool model augmentation from responses.
crates/service/src/apikey/apikey_models.rs Implements prune RPC behavior; filters/purges Codex image tool model; expands deletion cleanup; adds tests.
crates/core/src/storage/model_sources.rs Adds helper to delete model source routes for a “platform model”.
crates/core/src/storage/model_options.rs Prunes default model-group entries before inserting default options.
crates/core/src/storage/model_groups.rs Adds pruning and reference-deletion helpers for model groups.
apps/src/lib/i18n/messages/en.ts Adds UI strings for the prune action and outcomes.
apps/src/lib/api/transport-web-commands.ts Wires new web command to the prune RPC method.
apps/src/lib/api/account-client.ts Adds client method to call prune RPC and normalize the result.
apps/src/hooks/useManagedModels.ts Adds mutation + UX feedback for prune action; exposes pending state.
apps/src/app/models/page.tsx Adds a destructive “prune stale remote models” button and disables actions while pending.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +194 to +197
"apikey/modelCatalogPruneStaleRemote" => super::value_or_error(
apikey_models::prune_stale_remote_managed_model_catalog()
.and_then(|catalog| filter_catalog_for_actor(actor, catalog)),
),
Comment on lines +129 to +143
pub fn prune_default_model_group_models_not_in_catalog(&self) -> Result<()> {
self.conn.execute(
"DELETE FROM model_group_models
WHERE group_id IN (SELECT id FROM model_groups WHERE is_default = 1)
AND platform_model_slug NOT IN (
SELECT slug
FROM model_catalog_models
WHERE scope = 'default'
AND COALESCE(supported_in_api, 1) = 1
AND TRIM(slug) <> ''
)",
[],
)?;
Ok(())
}
Comment on lines +334 to +336
storage
.prune_default_model_group_models_not_in_catalog()
.map_err(|err| format!("prune default model group failed: {err}"))?;
}

fn result_from_storage(storage: &Storage) -> Result<ModelGroupListResult, String> {
crate::apikey_models::read_managed_model_catalog_from_storage(storage)?;
Comment on lines +372 to +390
pub fn delete_model_source_routes_for_platform_model(
&self,
platform_model_slug: &str,
) -> Result<()> {
let slug = normalize_text(platform_model_slug);
if slug.is_empty() {
return Ok(());
}
self.conn.execute(
"DELETE FROM model_source_mappings
WHERE platform_model_slug = ?1 OR upstream_model = ?1",
params![&slug],
)?;
self.conn.execute(
"DELETE FROM model_source_models WHERE upstream_model = ?1",
params![&slug],
)?;
Ok(())
}
@YQYANG2233 YQYANG2233 marked this pull request as ready for review June 3, 2026 09:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants