fix(shell): turns read the auth scheme and BYOK status from the live catalog
reconstruct_full_config and the subagent spawn resolved both from a disk reload that never holds fetched entries, so a fetched Messages model (anthropic, minimax) went out with Authorization: Bearer instead of x-api-key.
This commit is contained in:
1 parent
2ca1f3baa7
commit
eb86d7ec26
3 files changed
+47
-4
No files matched your search
@@ -3960,6 +3960,18 @@ pub fn resolve_model_auth_facts(model_id: &str) -> ModelAuthFacts {
|
||||
},
|
||||
})
|
||||
}
|
||||
/// Auth facts of a catalog entry the caller already holds. A fetched entry
|
||||
/// exists only in the live catalog, never in a disk reload.
|
||||
pub(crate) fn auth_facts_of(entry: &ModelEntry) -> ModelAuthFacts {
|
||||
ModelAuthFacts {
|
||||
byok: if entry.has_own_credentials() {
|
||||
ModelByok::Byok
|
||||
} else {
|
||||
ModelByok::NotByok
|
||||
},
|
||||
auth_scheme: entry.info().auth_scheme,
|
||||
}
|
||||
}
|
||||
fn byok_from_lookup(lookup: &ModelLookup) -> ModelByok {
|
||||
match lookup {
|
||||
ModelLookup::ConfigUnavailable => ModelByok::Unknown,
|
||||
@@ -5274,6 +5286,17 @@ reasoning_effort = "low"
|
||||
auth_scheme: Default::default(),
|
||||
}
|
||||
}
|
||||
/// A fetched entry's scheme and BYOK status come from the entry itself.
|
||||
#[test]
|
||||
fn auth_facts_come_from_the_held_entry() {
|
||||
let mut model = test_model_entry("claude-x", "https://gw.example/v1", None, None, None);
|
||||
model.info.auth_scheme = AuthScheme::XApiKey;
|
||||
let facts = auth_facts_of(&model);
|
||||
assert_eq!(facts.auth_scheme, AuthScheme::XApiKey);
|
||||
assert_eq!(facts.byok, ModelByok::NotByok);
|
||||
model.api_key = Some("sk-own".into());
|
||||
assert_eq!(auth_facts_of(&model).byok, ModelByok::Byok);
|
||||
}
|
||||
#[test]
|
||||
fn x_api_key_auth_scheme_flows_from_config_to_sampler() {
|
||||
let mut model = test_model_entry(
|
||||
|
||||
@@ -897,9 +897,17 @@ async fn read_parent_sampling_config(
|
||||
creds.alpha_test_key.as_deref(),
|
||||
&cfg.base_url,
|
||||
);
|
||||
let auth_scheme = crate::agent::config::try_resolve_model_credentials(&cfg.model, None)
|
||||
.map(|r| r.auth_scheme)
|
||||
.unwrap_or_default();
|
||||
let auth_scheme = crate::agent::models::entry_for_slug(
|
||||
&ctx.available_models,
|
||||
Some(ctx.model_id.0.as_ref()),
|
||||
&cfg.model,
|
||||
)
|
||||
.map(|entry| crate::agent::config::auth_facts_of(entry).auth_scheme)
|
||||
.or_else(|| {
|
||||
crate::agent::config::try_resolve_model_credentials(&cfg.model, None)
|
||||
.map(|r| r.auth_scheme)
|
||||
})
|
||||
.unwrap_or_default();
|
||||
// Claude Pro/Max OAuth Messages adaptation inherits from the parent
|
||||
// model's platform (claude-pro-max → true); every other platform,
|
||||
// and BYOK, → false, so the API-key paths stay byte-identical.
|
||||
|
||||
@@ -264,6 +264,16 @@ impl SessionActor {
|
||||
fn aux_model_auth_facts(&self, model_id: &str) -> crate::agent::config::ModelAuthFacts {
|
||||
self.resolve_auth_facts(model_id, false)
|
||||
}
|
||||
/// Facts from the live catalog entry the session samples against.
|
||||
fn live_auth_facts(&self, model_id: &str) -> Option<crate::agent::config::ModelAuthFacts> {
|
||||
let models = self.models_manager.models();
|
||||
crate::agent::models::entry_for_slug(
|
||||
&models,
|
||||
self.selected_catalog_key().as_deref(),
|
||||
model_id,
|
||||
)
|
||||
.map(crate::agent::config::auth_facts_of)
|
||||
}
|
||||
/// Shared body of [`Self::model_auth_facts`] / [`Self::aux_model_auth_facts`].
|
||||
/// `memoize` is the ONLY difference, so the two can never resolve differently.
|
||||
fn resolve_auth_facts(
|
||||
@@ -278,7 +288,9 @@ impl SessionActor {
|
||||
{
|
||||
return *facts;
|
||||
}
|
||||
let fresh = crate::agent::config::resolve_model_auth_facts(model_id);
|
||||
let fresh = self
|
||||
.live_auth_facts(model_id)
|
||||
.unwrap_or_else(|| crate::agent::config::resolve_model_auth_facts(model_id));
|
||||
if fresh.byok == ModelByok::Unknown {
|
||||
if let Some((cached_id, facts)) = self.model_auth_facts.borrow().as_ref()
|
||||
&& cached_id == model_id
|
||||
|
||||
Reference in new issue
Block a user