mirror of
https://github.com/Gitlawb/openclaude.git
synced 2026-11-06 20:58:14 -04:00
fix(gemini-vertex): wire flag into env-file allowlist, test scrubs and truthiness
Addresses maintainer review on PR #1614: - envFile.ts: add CLAUDE_CODE_USE_GEMINI_VERTEX plus GEMINI_VERTEX_* / GOOGLE_APPLICATION_CREDENTIALS / GCLOUD_PROJECT / GOOGLE_PROJECT_ID to ALLOWED_ENV_FILE_KEYS so --provider-env-file .env no longer silently rejects the documented Vertex setup. Adds a PROVIDER_SELECTION_FLAGS-derived parity test plus a full Vertex .env load test. - Add CLAUDE_CODE_USE_GEMINI_VERTEX to the provider env scrub/restore lists in betas, conversationRecovery, model, withRetry and promptCacheBreakDetection tests to prevent cross-test flag leakage. - providerFlag.applyModelFlagFromArgs and StartupScreen.detectProvider: use isEnvTruthy for all provider flags instead of literal '1'/'true' checks, removing the Vertex-only inconsistency. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
1ac5ab6171
commit
5e975fff48
@@ -21,6 +21,7 @@ type SettingsModule = typeof import('../../utils/settings/settings.js')
|
||||
const originalEnv = {
|
||||
CLAUDE_CODE_USE_OPENAI: process.env.CLAUDE_CODE_USE_OPENAI,
|
||||
CLAUDE_CODE_USE_GEMINI: process.env.CLAUDE_CODE_USE_GEMINI,
|
||||
CLAUDE_CODE_USE_GEMINI_VERTEX: process.env.CLAUDE_CODE_USE_GEMINI_VERTEX,
|
||||
CLAUDE_CODE_USE_GITHUB: process.env.CLAUDE_CODE_USE_GITHUB,
|
||||
CLAUDE_CODE_USE_MISTRAL: process.env.CLAUDE_CODE_USE_MISTRAL,
|
||||
CLAUDE_CODE_USE_BEDROCK: process.env.CLAUDE_CODE_USE_BEDROCK,
|
||||
@@ -202,6 +203,10 @@ afterEach(() => {
|
||||
settingsForTest = {}
|
||||
restoreEnv('CLAUDE_CODE_USE_OPENAI', originalEnv.CLAUDE_CODE_USE_OPENAI)
|
||||
restoreEnv('CLAUDE_CODE_USE_GEMINI', originalEnv.CLAUDE_CODE_USE_GEMINI)
|
||||
restoreEnv(
|
||||
'CLAUDE_CODE_USE_GEMINI_VERTEX',
|
||||
originalEnv.CLAUDE_CODE_USE_GEMINI_VERTEX,
|
||||
)
|
||||
restoreEnv('CLAUDE_CODE_USE_GITHUB', originalEnv.CLAUDE_CODE_USE_GITHUB)
|
||||
restoreEnv('CLAUDE_CODE_USE_MISTRAL', originalEnv.CLAUDE_CODE_USE_MISTRAL)
|
||||
restoreEnv('CLAUDE_CODE_USE_BEDROCK', originalEnv.CLAUDE_CODE_USE_BEDROCK)
|
||||
|
||||
@@ -85,10 +85,10 @@ const LOGO_CLAUDE = [
|
||||
|
||||
export function detectProvider(modelOverride?: string): { name: string; model: string; baseUrl: string; isLocal: boolean } {
|
||||
const useGeminiVertex = isEnvTruthy(process.env.CLAUDE_CODE_USE_GEMINI_VERTEX)
|
||||
const useGemini = process.env.CLAUDE_CODE_USE_GEMINI === '1' || process.env.CLAUDE_CODE_USE_GEMINI === 'true'
|
||||
const useGithub = process.env.CLAUDE_CODE_USE_GITHUB === '1' || process.env.CLAUDE_CODE_USE_GITHUB === 'true'
|
||||
const useOpenAI = process.env.CLAUDE_CODE_USE_OPENAI === '1' || process.env.CLAUDE_CODE_USE_OPENAI === 'true'
|
||||
const useMistral = process.env.CLAUDE_CODE_USE_MISTRAL === '1' || process.env.CLAUDE_CODE_USE_MISTRAL === 'true'
|
||||
const useGemini = isEnvTruthy(process.env.CLAUDE_CODE_USE_GEMINI)
|
||||
const useGithub = isEnvTruthy(process.env.CLAUDE_CODE_USE_GITHUB)
|
||||
const useOpenAI = isEnvTruthy(process.env.CLAUDE_CODE_USE_OPENAI)
|
||||
const useMistral = isEnvTruthy(process.env.CLAUDE_CODE_USE_MISTRAL)
|
||||
|
||||
if (useGeminiVertex) {
|
||||
// Use the shared resolvers so this display matches the runtime/provider
|
||||
|
||||
@@ -50,6 +50,7 @@ const PROVIDER_ENV_KEYS = [
|
||||
'CLAUDE_CODE_USE_OPENAI',
|
||||
'CLAUDE_CODE_USE_GITHUB',
|
||||
'CLAUDE_CODE_USE_GEMINI',
|
||||
'CLAUDE_CODE_USE_GEMINI_VERTEX',
|
||||
'CLAUDE_CODE_USE_MISTRAL',
|
||||
'CLAUDE_CODE_USE_BEDROCK',
|
||||
'CLAUDE_CODE_USE_VERTEX',
|
||||
|
||||
@@ -22,6 +22,7 @@ let originalProvidersModule: ProvidersModule | undefined
|
||||
const envKeys = [
|
||||
'CLAUDE_CODE_USE_OPENAI',
|
||||
'CLAUDE_CODE_USE_GEMINI',
|
||||
'CLAUDE_CODE_USE_GEMINI_VERTEX',
|
||||
'CLAUDE_CODE_USE_GITHUB',
|
||||
'CLAUDE_CODE_USE_BEDROCK',
|
||||
'CLAUDE_CODE_USE_VERTEX',
|
||||
|
||||
@@ -22,6 +22,7 @@ import { setSdkBetas } from '../bootstrap/state.js'
|
||||
const PROVIDER_ENV_KEYS = [
|
||||
'CLAUDE_CODE_USE_OPENAI',
|
||||
'CLAUDE_CODE_USE_GEMINI',
|
||||
'CLAUDE_CODE_USE_GEMINI_VERTEX',
|
||||
'CLAUDE_CODE_USE_MISTRAL',
|
||||
'CLAUDE_CODE_USE_GITHUB',
|
||||
'CLAUDE_CODE_USE_BEDROCK',
|
||||
|
||||
@@ -17,6 +17,7 @@ const tempDirs: string[] = []
|
||||
const originalSimple = process.env.CLAUDE_CODE_SIMPLE
|
||||
const providerEnvKeys = [
|
||||
'CLAUDE_CODE_USE_GEMINI',
|
||||
'CLAUDE_CODE_USE_GEMINI_VERTEX',
|
||||
'CLAUDE_CODE_USE_MISTRAL',
|
||||
'CLAUDE_CODE_USE_GITHUB',
|
||||
'CLAUDE_CODE_USE_BEDROCK',
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
reapplyRememberedEnvFileValues,
|
||||
rememberLoadedEnvFileValues,
|
||||
} from './envFile.js'
|
||||
import { PROVIDER_SELECTION_FLAGS } from './providerSelectionFlags.js'
|
||||
|
||||
const TEST_ENV_KEYS = [
|
||||
'NODE_OPTIONS',
|
||||
@@ -21,6 +22,16 @@ const TEST_ENV_KEYS = [
|
||||
'OPENAI_API_KEY',
|
||||
'OPENAI_BASE_URL',
|
||||
'OPENAI_MODEL',
|
||||
...PROVIDER_SELECTION_FLAGS,
|
||||
'GEMINI_ACCESS_TOKEN',
|
||||
'GEMINI_VERTEX_PROJECT',
|
||||
'GEMINI_VERTEX_LOCATION',
|
||||
'GEMINI_VERTEX_MODEL',
|
||||
'GEMINI_VERTEX_AUTH_MODE',
|
||||
'GOOGLE_APPLICATION_CREDENTIALS',
|
||||
'GOOGLE_CLOUD_PROJECT',
|
||||
'GCLOUD_PROJECT',
|
||||
'GOOGLE_PROJECT_ID',
|
||||
'WEB_AUTH_HEADER',
|
||||
'WEB_AUTH_SCHEME',
|
||||
'WEB_BODY_TEMPLATE',
|
||||
@@ -335,6 +346,49 @@ describe('loadEnvFile', () => {
|
||||
expect(process.env.CODEX_AUTH_JSON_PATH).toBe('/tmp/codex-auth.json')
|
||||
})
|
||||
|
||||
it('accepts every registered provider-selection flag', () => {
|
||||
// Guards against a new CLAUDE_CODE_USE_* flag (like Gemini Vertex) being
|
||||
// added to PROVIDER_SELECTION_FLAGS but silently rejected by the env-file
|
||||
// allowlist, which would break --provider-env-file end-to-end wiring.
|
||||
const filePath = writeTempEnvFile(
|
||||
PROVIDER_SELECTION_FLAGS.map(flag => `${flag}=1`).join('\n'),
|
||||
)
|
||||
|
||||
const loaded = loadEnvFile(filePath)
|
||||
|
||||
for (const flag of PROVIDER_SELECTION_FLAGS) {
|
||||
expect(loaded[flag]).toBe('1')
|
||||
expect(process.env[flag]).toBe('1')
|
||||
}
|
||||
})
|
||||
|
||||
it('loads the documented Gemini Vertex provider setup', () => {
|
||||
const filePath = writeTempEnvFile([
|
||||
'CLAUDE_CODE_USE_GEMINI_VERTEX=1',
|
||||
'GEMINI_VERTEX_PROJECT=my-project',
|
||||
'GEMINI_VERTEX_LOCATION=us-central1',
|
||||
'GEMINI_VERTEX_MODEL=gemini-2.0-flash',
|
||||
'GEMINI_VERTEX_AUTH_MODE=adc',
|
||||
'GOOGLE_APPLICATION_CREDENTIALS=/tmp/sa.json',
|
||||
'GCLOUD_PROJECT=my-project',
|
||||
'GOOGLE_PROJECT_ID=my-project',
|
||||
].join('\n'))
|
||||
|
||||
const loaded = loadEnvFile(filePath)
|
||||
|
||||
expect(loaded).toEqual({
|
||||
CLAUDE_CODE_USE_GEMINI_VERTEX: '1',
|
||||
GEMINI_VERTEX_PROJECT: 'my-project',
|
||||
GEMINI_VERTEX_LOCATION: 'us-central1',
|
||||
GEMINI_VERTEX_MODEL: 'gemini-2.0-flash',
|
||||
GEMINI_VERTEX_AUTH_MODE: 'adc',
|
||||
GOOGLE_APPLICATION_CREDENTIALS: '/tmp/sa.json',
|
||||
GCLOUD_PROJECT: 'my-project',
|
||||
GOOGLE_PROJECT_ID: 'my-project',
|
||||
})
|
||||
expect(process.env.CLAUDE_CODE_USE_GEMINI_VERTEX).toBe('1')
|
||||
})
|
||||
|
||||
it('rejects unsupported variables before mutating process environment', () => {
|
||||
const filePath = writeTempEnvFile([
|
||||
'OPENAI_MODEL=from-file',
|
||||
|
||||
@@ -37,6 +37,7 @@ const ALLOWED_ENV_FILE_KEYS = new Set([
|
||||
'CLAUDE_CODE_USE_BEDROCK',
|
||||
'CLAUDE_CODE_USE_FOUNDRY',
|
||||
'CLAUDE_CODE_USE_GEMINI',
|
||||
'CLAUDE_CODE_USE_GEMINI_VERTEX',
|
||||
'CLAUDE_CODE_USE_GITHUB',
|
||||
'CLAUDE_CODE_USE_MISTRAL',
|
||||
'CLAUDE_CODE_USE_OPENAI',
|
||||
@@ -53,11 +54,16 @@ const ALLOWED_ENV_FILE_KEYS = new Set([
|
||||
'FIRECRAWL_API_KEY',
|
||||
'FIRECRAWL_API_URL',
|
||||
'FIREWORKS_API_KEY',
|
||||
'GCLOUD_PROJECT',
|
||||
'GEMINI_ACCESS_TOKEN',
|
||||
'GEMINI_API_KEY',
|
||||
'GEMINI_AUTH_MODE',
|
||||
'GEMINI_BASE_URL',
|
||||
'GEMINI_MODEL',
|
||||
'GEMINI_VERTEX_AUTH_MODE',
|
||||
'GEMINI_VERTEX_LOCATION',
|
||||
'GEMINI_VERTEX_MODEL',
|
||||
'GEMINI_VERTEX_PROJECT',
|
||||
'GH_TOKEN',
|
||||
'GITHUB_COPILOT_ALLOW_SUBAGENTS',
|
||||
'GITHUB_COPILOT_FORCE_SYNC_SUBAGENTS',
|
||||
@@ -65,8 +71,10 @@ const ALLOWED_ENV_FILE_KEYS = new Set([
|
||||
'GITHUB_COPILOT_OPTIMIZATION_DISABLED',
|
||||
'GITHUB_TOKEN',
|
||||
'GOOGLE_API_KEY',
|
||||
'GOOGLE_APPLICATION_CREDENTIALS',
|
||||
'GOOGLE_CLOUD_PROJECT',
|
||||
'GOOGLE_CSE_ID',
|
||||
'GOOGLE_PROJECT_ID',
|
||||
'GROQ_API_KEY',
|
||||
'HICAP_API_KEY',
|
||||
'JINA_API_KEY',
|
||||
|
||||
@@ -225,18 +225,10 @@ export function applyModelFlagFromArgs(args: string[]): void {
|
||||
if (!model) return
|
||||
|
||||
const useGeminiVertex = isEnvTruthy(process.env.CLAUDE_CODE_USE_GEMINI_VERTEX)
|
||||
const useGemini =
|
||||
process.env.CLAUDE_CODE_USE_GEMINI === '1' ||
|
||||
process.env.CLAUDE_CODE_USE_GEMINI === 'true'
|
||||
const useMistral =
|
||||
process.env.CLAUDE_CODE_USE_MISTRAL === '1' ||
|
||||
process.env.CLAUDE_CODE_USE_MISTRAL === 'true'
|
||||
const useOpenAI =
|
||||
process.env.CLAUDE_CODE_USE_OPENAI === '1' ||
|
||||
process.env.CLAUDE_CODE_USE_OPENAI === 'true'
|
||||
const useGithub =
|
||||
process.env.CLAUDE_CODE_USE_GITHUB === '1' ||
|
||||
process.env.CLAUDE_CODE_USE_GITHUB === 'true'
|
||||
const useGemini = isEnvTruthy(process.env.CLAUDE_CODE_USE_GEMINI)
|
||||
const useMistral = isEnvTruthy(process.env.CLAUDE_CODE_USE_MISTRAL)
|
||||
const useOpenAI = isEnvTruthy(process.env.CLAUDE_CODE_USE_OPENAI)
|
||||
const useGithub = isEnvTruthy(process.env.CLAUDE_CODE_USE_GITHUB)
|
||||
|
||||
if (useGeminiVertex) {
|
||||
process.env.GEMINI_VERTEX_MODEL = model
|
||||
|
||||
Reference in New Issue
Block a user