fix(cli): honor --openai-api-key in non-interactive auth validation (#3187)

validateAuthMethod's pre-flight check only inspected OPENAI_API_KEY (and
settings.security.auth.apiKey), so credentials supplied via --openai-api-key
were rejected even though refreshAuth would have accepted them. macOS users
were unaffected because OPENAI_API_KEY is commonly exported in their shell
profile; on Linux without that env var, the CLI failed to start.

hasApiKeyForAuth now prefers the API key already resolved into
generationConfig.apiKey when a Config is provided. The unified resolver
folds CLI flags, env vars, settings, and modelProvider envKey lookups into
this single value, so validation matches runtime behavior.

Fixes #3171
This commit is contained in:
tanzhenxin 2026-04-13 18:06:27 +08:00 committed by GitHub
parent 9cdf7bd7c8
commit 62867702f7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 77 additions and 0 deletions

View file

@ -29,6 +29,7 @@ function createMockConfig(overrides?: Partial<Config>): Config {
const baseModelsConfig = {
getModel: vi.fn().mockReturnValue('default-model'),
getCurrentAuthType: vi.fn().mockReturnValue(AuthType.QWEN_OAUTH),
getGenerationConfig: vi.fn().mockReturnValue({}),
} as unknown as ModelsConfig;
const baseConfig: Partial<Config> = {
refreshAuth: vi.fn().mockResolvedValue('refreshed'),
@ -169,6 +170,7 @@ describe('validateNonInterActiveAuth', () => {
getModelsConfig: vi.fn().mockReturnValue({
getModel: vi.fn().mockReturnValue('default-model'),
getCurrentAuthType: vi.fn().mockReturnValue(AuthType.USE_OPENAI),
getGenerationConfig: vi.fn().mockReturnValue({}),
}),
});
await validateNonInteractiveAuth(
@ -185,6 +187,7 @@ describe('validateNonInterActiveAuth', () => {
getModelsConfig: vi.fn().mockReturnValue({
getModel: vi.fn().mockReturnValue('default-model'),
getCurrentAuthType: vi.fn().mockReturnValue(AuthType.QWEN_OAUTH),
getGenerationConfig: vi.fn().mockReturnValue({}),
}),
});
await validateNonInteractiveAuth(
@ -249,6 +252,7 @@ describe('validateNonInterActiveAuth', () => {
getModelsConfig: vi.fn().mockReturnValue({
getModel: vi.fn().mockReturnValue('default-model'),
getCurrentAuthType: vi.fn().mockReturnValue(AuthType.USE_OPENAI),
getGenerationConfig: vi.fn().mockReturnValue({}),
}),
});
await validateNonInteractiveAuth(
@ -267,6 +271,7 @@ describe('validateNonInterActiveAuth', () => {
getModelsConfig: vi.fn().mockReturnValue({
getModel: vi.fn().mockReturnValue('default-model'),
getCurrentAuthType: vi.fn().mockReturnValue(AuthType.USE_OPENAI),
getGenerationConfig: vi.fn().mockReturnValue({}),
}),
});
try {