fix(providers): use Bearer auth for Gemini CLI OAuth tokens
* fix(providers): use Bearer auth for Gemini CLI OAuth tokens When credentials come from ~/.gemini/oauth_creds.json (Gemini CLI), send them as Authorization: Bearer header instead of ?key= query parameter. API keys from env vars or config continue using ?key=. Fixes #194 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(gemini): harden OAuth bearer auth flow and tests * fix(gemini): granular auth source tracking and review fixes Build on chumyin's auth model refactor with: - Expand GeminiAuth to 4 variants (ExplicitKey/EnvGeminiKey/EnvGoogleKey/ OAuthToken) so auth_source() uses stored discriminant without re-reading env vars at call time - Add is_api_key()/credential() helpers on the enum - Upgrade expired OAuth token log from debug to warn - Add tests: provider_rejects_empty_key, auth_source_explicit_key, auth_source_none_without_credentials Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style: apply rustfmt to fix CI lint failures Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: root <root@instance-20220913-1738.vcn09131738.oraclevcn.com> Co-authored-by: argenis de la rosa <theonlyhennygod@gmail.com>
This commit is contained in:
parent
e057bf4128
commit
49bb20f961
15 changed files with 358 additions and 148 deletions
|
|
@ -181,7 +181,10 @@ mod tests {
|
|||
.iter()
|
||||
.zip(mocks.iter())
|
||||
.map(|((name, _), mock)| {
|
||||
(name.to_string(), Box::new(Arc::clone(mock)) as Box<dyn Provider>)
|
||||
(
|
||||
name.to_string(),
|
||||
Box::new(Arc::clone(mock)) as Box<dyn Provider>,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
|
@ -198,11 +201,7 @@ mod tests {
|
|||
})
|
||||
.collect();
|
||||
|
||||
let router = RouterProvider::new(
|
||||
provider_list,
|
||||
route_list,
|
||||
"default-model".to_string(),
|
||||
);
|
||||
let router = RouterProvider::new(provider_list, route_list, "default-model".to_string());
|
||||
|
||||
(router, mocks)
|
||||
}
|
||||
|
|
@ -270,7 +269,10 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn non_hint_model_uses_default_provider() {
|
||||
let (router, mocks) = make_router(
|
||||
vec![("primary", "primary-response"), ("secondary", "secondary-response")],
|
||||
vec![
|
||||
("primary", "primary-response"),
|
||||
("secondary", "secondary-response"),
|
||||
],
|
||||
vec![("code", "secondary", "codellama")],
|
||||
);
|
||||
|
||||
|
|
@ -285,10 +287,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn resolve_preserves_model_for_non_hints() {
|
||||
let (router, _) = make_router(
|
||||
vec![("default", "ok")],
|
||||
vec![],
|
||||
);
|
||||
let (router, _) = make_router(vec![("default", "ok")], vec![]);
|
||||
|
||||
let (idx, model) = router.resolve("gpt-4o");
|
||||
assert_eq!(idx, 0);
|
||||
|
|
@ -320,10 +319,7 @@ mod tests {
|
|||
|
||||
#[tokio::test]
|
||||
async fn warmup_calls_all_providers() {
|
||||
let (router, _) = make_router(
|
||||
vec![("a", "ok"), ("b", "ok")],
|
||||
vec![],
|
||||
);
|
||||
let (router, _) = make_router(vec![("a", "ok"), ("b", "ok")], vec![]);
|
||||
|
||||
// Warmup should not error
|
||||
assert!(router.warmup().await.is_ok());
|
||||
|
|
@ -333,7 +329,10 @@ mod tests {
|
|||
async fn chat_with_system_passes_system_prompt() {
|
||||
let mock = Arc::new(MockProvider::new("response"));
|
||||
let router = RouterProvider::new(
|
||||
vec![("default".into(), Box::new(Arc::clone(&mock)) as Box<dyn Provider>)],
|
||||
vec![(
|
||||
"default".into(),
|
||||
Box::new(Arc::clone(&mock)) as Box<dyn Provider>,
|
||||
)],
|
||||
vec![],
|
||||
"model".into(),
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue