fix(models): 模型发现遇到别名冲突时跳过该项而非整批回滚 - #910
Merged
Merged
Conversation
…f aborting the batch UpsertDiscovered calls ensureModelPublicIDNotAlias inside the transaction and returns on conflict, so one alias collision rolls back the whole batch and silently drops unrelated new models. preserveModelRouteAlias registers the old public ID as a compatibility alias on every route rename, so a single historical rename can permanently hide every future model of that provider. Skip the conflicting entry and keep the rest of the batch. Non-conflict errors still propagate. The skipped entry could not have been inserted anyway, so reachable state is unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
ModelRepository.UpsertDiscovered在事务内对每个发现到的上游模型调用ensureModelPublicIDNotAlias,冲突时直接return err。由于该调用位于Transaction闭包内,一个模型的别名冲突会让整批发现回滚,同批次里本身无冲突的新模型一并被丢弃。触发条件不罕见:
preserveModelRouteAlias会在路由改名时自动把旧的 public_id 登记为兼容别名。此后discoveredRouteDefaults为该上游模型算出的规范 public_id 正好等于这个别名,冲突稳定复现 —— 于是一次历史改名可以永久堵死该 provider 的全部后续模型发现。实际观察到的现象:某部署把
Build/grok-4.5改名为Build/build-grok-4.5,model_route_aliases留下('Build/grok-4.5', 15)。之后上游/models开始返回grok-4.6,account_model_capabilities里数千个账号都记录了该能力(账号快照走ReplaceAccountCapabilities,不经过别名检查,因此成功),但model_routes中 provider=grok_build始终只有改名后的那条和 composer 两条,grok-4.6一直进不去,对外/v1/models也看不到,只能手工建路由绕过。日志里表现为反复的model_etag_refresh_failed,错误都是同一条repository: conflict: 模型公开 ID "Build/grok-4.5" 已被路由 15 保留为兼容名称。改动
别名冲突时跳过该模型、继续处理同批其余模型;非冲突错误仍然向上返回,保持原有失败语义。冲突项本来就无法插入,跳过不改变可达状态,只是不再牵连同批其他模型。
测试
新增
TestUpsertDiscoveredAliasCollisionDropsWholeBatch,按真实部署的顺序复现:先发现grok-4.5,改名留下兼容别名,再以["grok-4.5", "grok-4.6"]触发发现。修复前该用例失败:
UpsertDiscovered返回repository: conflict: 模型公开 ID "Build/grok-4.5" 已被路由 1 保留为兼容名称,且grok-4.6未落库。修复后通过。本地:
go build ./...、go vet ./...、go test ./...全绿。说明
这与 #906 不是同一处:#906 修的是
NormalizeAccountModelCapabilities(账号能力快照里补回grok-4.5),本 PR 修的是UpsertDiscovered(公开路由目录进不去新模型)。两者互补 —— 账号能力表能写成功正是因为它不经过别名检查,而路由表被别名卡死,所以 #906 合入后本问题依然存在。