feat: add Gemini ADC and access token auth (#312)

* feat: add Gemini ADC and access token auth

* feat: add Gemini token and ADC provider setup

* feat: add Gemini token and ADC provider setup

* fix: honor Gemini auth mode on restart
This commit is contained in:
Vasanth T
2026-04-04 15:07:17 +05:30
committed by GitHub
parent 280c9732f5
commit ea335aeddc
15 changed files with 1128 additions and 130 deletions

View File

@@ -23,6 +23,8 @@
import { APIError } from '@anthropic-ai/sdk'
import { isEnvTruthy } from '../../utils/envUtils.js'
import { resolveGeminiCredential } from '../../utils/geminiAuth.js'
import { hydrateGeminiAccessTokenFromSecureStorage } from '../../utils/geminiCredentials.js'
import { hydrateGithubModelsTokenFromSecureStorage } from '../../utils/githubModelsCredentials.js'
import {
codexStreamToAnthropic,
@@ -46,6 +48,7 @@ type SecretValueSource = Partial<{
CODEX_API_KEY: string
GEMINI_API_KEY: string
GOOGLE_API_KEY: string
GEMINI_ACCESS_TOKEN: string
}>
const GITHUB_MODELS_DEFAULT_BASE = 'https://models.github.ai/inference'
@@ -893,7 +896,9 @@ class OpenAIShimMessages {
...(options?.headers ?? {}),
}
const apiKey = this.providerOverride?.apiKey ?? process.env.OPENAI_API_KEY ?? ''
const isGemini = isEnvTruthy(process.env.CLAUDE_CODE_USE_GEMINI)
const apiKey =
this.providerOverride?.apiKey ?? process.env.OPENAI_API_KEY ?? ''
// Detect Azure endpoints by hostname (not raw URL) to prevent bypass via
// path segments like https://evil.com/cognitiveservices.azure.com/
let isAzure = false
@@ -910,6 +915,14 @@ class OpenAIShimMessages {
} else {
headers.Authorization = `Bearer ${apiKey}`
}
} else if (isGemini) {
const geminiCredential = await resolveGeminiCredential(process.env)
if (geminiCredential.kind !== 'none') {
headers.Authorization = `Bearer ${geminiCredential.credential}`
if (geminiCredential.projectId) {
headers['x-goog-user-project'] = geminiCredential.projectId
}
}
}
if (isGithub) {
@@ -1105,6 +1118,7 @@ export function createOpenAIShimClient(options: {
reasoningEffort?: 'low' | 'medium' | 'high' | 'xhigh'
providerOverride?: { model: string; baseURL: string; apiKey: string }
}): unknown {
hydrateGeminiAccessTokenFromSecureStorage()
hydrateGithubModelsTokenFromSecureStorage()
// When Gemini provider is active, map Gemini env vars to OpenAI-compatible ones
@@ -1113,8 +1127,11 @@ export function createOpenAIShimClient(options: {
process.env.OPENAI_BASE_URL ??=
process.env.GEMINI_BASE_URL ??
'https://generativelanguage.googleapis.com/v1beta/openai'
process.env.OPENAI_API_KEY ??=
process.env.GEMINI_API_KEY ?? process.env.GOOGLE_API_KEY ?? ''
const geminiApiKey =
process.env.GEMINI_API_KEY ?? process.env.GOOGLE_API_KEY
if (geminiApiKey && !process.env.OPENAI_API_KEY) {
process.env.OPENAI_API_KEY = geminiApiKey
}
if (process.env.GEMINI_MODEL && !process.env.OPENAI_MODEL) {
process.env.OPENAI_MODEL = process.env.GEMINI_MODEL
}