mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-08 18:37:46 +08:00
fix(routing): keep global model names out of provider alias reach
A provider model can be addressed by its upstream name or by any of its `provider_model_mappings` entries, and neither name is published in the model catalog, which lists global model names only. Resolution ran per API format, so an alias could win a format the real global model had no provider in: a `claude:messages` client asking for `gemini-3.8-flash` landed on the provider that merely renames its own `gemini-3.8-flash-cursor` model to `gemini-3.8-flash` on the way upstream, and the separate global model stopped distinguishing the two routes. Treat global model names as a reserved namespace instead: when the request names an active global model, only rows bound to it may serve it, whatever API format they sit in. Rows in hand answer that question for free whenever one of them is bound to a global model of that name, so the lookup stays off the path ordinary requests take. Authorization resolves the same way, so an API key's allowed models cannot be satisfied through a resolution candidate planning will no longer make. A request naming a model that is not a global model keeps every matching rule, so addressing a provider variant by its upstream name still works. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -185,6 +185,16 @@ impl MinimalCandidateSelectionRowSource for GatewayDataState {
|
||||
) -> Result<Vec<StoredMinimalCandidateSelectionRow>, DataLayerError> {
|
||||
self.list_pool_key_candidate_rows_for_group(query).await
|
||||
}
|
||||
|
||||
async fn read_reserved_global_model_name(
|
||||
&self,
|
||||
model_name: &str,
|
||||
) -> Result<Option<String>, DataLayerError> {
|
||||
Ok(self
|
||||
.get_public_global_model_by_name(model_name)
|
||||
.await?
|
||||
.map(|global_model| global_model.name))
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
|
||||
Reference in New Issue
Block a user