Merge pull request #81 from Vasanthdev2004/third-party-setup-fix

fix: skip Anthropic setup flow for third-party providers
This commit is contained in:
Kevin Codex
2026-04-02 07:37:35 +08:00
committed by GitHub
4 changed files with 71 additions and 11 deletions

View File

@@ -25,6 +25,7 @@ import { isEnvTruthy, isRunningOnHomespace } from './utils/envUtils.js';
import { type FpsMetrics, FpsTracker } from './utils/fpsTracker.js'; import { type FpsMetrics, FpsTracker } from './utils/fpsTracker.js';
import { updateGithubRepoPathMapping } from './utils/githubRepoPathMapping.js'; import { updateGithubRepoPathMapping } from './utils/githubRepoPathMapping.js';
import { applyConfigEnvironmentVariables } from './utils/managedEnv.js'; import { applyConfigEnvironmentVariables } from './utils/managedEnv.js';
import { usesAnthropicAccountFlow } from './utils/model/providers.js';
import type { PermissionMode } from './utils/permissions/PermissionMode.js'; import type { PermissionMode } from './utils/permissions/PermissionMode.js';
import { getBaseRenderOptions } from './utils/renderOptions.js'; import { getBaseRenderOptions } from './utils/renderOptions.js';
import { getSettingsWithAllErrors } from './utils/settings/allErrors.js'; import { getSettingsWithAllErrors } from './utils/settings/allErrors.js';
@@ -107,12 +108,12 @@ export async function showSetupScreens(root: Root, permissionMode: PermissionMod
return false; return false;
} }
const isOpenAIProvider = isEnvTruthy(process.env.CLAUDE_CODE_USE_OPENAI); const usesAnthropicSetup = usesAnthropicAccountFlow();
const config = getGlobalConfig(); const config = getGlobalConfig();
let onboardingShown = false; let onboardingShown = false;
// Skip onboarding dialog for OpenAI provider (no Anthropic account needed) // Skip onboarding dialog for third-party providers (no Anthropic account needed)
if (!isOpenAIProvider && (!config.theme || !config.hasCompletedOnboarding) // always show onboarding at least once if (usesAnthropicSetup && (!config.theme || !config.hasCompletedOnboarding) // always show onboarding at least once
) { ) {
onboardingShown = true; onboardingShown = true;
const { const {
@@ -133,9 +134,9 @@ export async function showSetupScreens(root: Root, permissionMode: PermissionMod
// Note: non-interactive sessions (CI/CD with -p) never reach showSetupScreens at all. // Note: non-interactive sessions (CI/CD with -p) never reach showSetupScreens at all.
// Skip permission checks in claubbit // Skip permission checks in claubbit
if (!isEnvTruthy(process.env.CLAUBBIT)) { if (!isEnvTruthy(process.env.CLAUBBIT)) {
// Skip trust dialog UI for OpenAI provider (no Anthropic auth), but still // Skip trust dialog UI for third-party providers (no Anthropic auth), but still
// run trust state initialization below so the REPL mounts correctly. // run trust state initialization below so the REPL mounts correctly.
if (!isOpenAIProvider && !checkHasTrustDialogAccepted()) { if (usesAnthropicSetup && !checkHasTrustDialogAccepted()) {
const { const {
TrustDialog TrustDialog
} = await import('./components/TrustDialog/TrustDialog.js'); } = await import('./components/TrustDialog/TrustDialog.js');
@@ -144,7 +145,7 @@ export async function showSetupScreens(root: Root, permissionMode: PermissionMod
// Signal that trust has been verified for this session. // Signal that trust has been verified for this session.
// GrowthBook checks this to decide whether to include auth headers. // GrowthBook checks this to decide whether to include auth headers.
// Critical for OpenAI provider: without this, downstream config lookups // Critical for third-party providers: without this, downstream config lookups
// may fail silently, preventing the REPL from mounting (frozen terminal). // may fail silently, preventing the REPL from mounting (frozen terminal).
setSessionTrustAccepted(true); setSessionTrustAccepted(true);
@@ -157,8 +158,8 @@ export async function showSetupScreens(root: Root, permissionMode: PermissionMod
// Now that trust is established, prefetch system context if it wasn't already // Now that trust is established, prefetch system context if it wasn't already
void getSystemContext(); void getSystemContext();
// Skip MCP approval dialogs for OpenAI provider (no interactive auth prompts) // Skip MCP approval dialogs for third-party providers (no interactive auth prompts)
if (!isOpenAIProvider) { if (usesAnthropicSetup) {
// If settings are valid, check for any mcp.json servers that need approval // If settings are valid, check for any mcp.json servers that need approval
const { const {
errors: allErrors errors: allErrors

View File

@@ -72,7 +72,7 @@ describe('Codex provider config', () => {
}) })
describe('Codex request translation', () => { describe('Codex request translation', () => {
test('disables strict mode for tools with optional parameters', () => { test('normalizes optional parameters into strict Responses schemas', () => {
const tools = convertToolsToResponsesTools([ const tools = convertToolsToResponsesTools([
{ {
name: 'Agent', name: 'Agent',
@@ -102,9 +102,10 @@ describe('Codex request translation', () => {
prompt: { type: 'string' }, prompt: { type: 'string' },
subagent_type: { type: 'string' }, subagent_type: { type: 'string' },
}, },
required: ['description', 'prompt'], required: ['description', 'prompt', 'subagent_type'],
additionalProperties: false, additionalProperties: false,
}, },
strict: true,
}, },
]) ])
}) })

View File

@@ -0,0 +1,54 @@
import { afterEach, expect, test } from 'bun:test'
import {
getAPIProvider,
usesAnthropicAccountFlow,
} from './providers.js'
const originalEnv = {
CLAUDE_CODE_USE_GEMINI: process.env.CLAUDE_CODE_USE_GEMINI,
CLAUDE_CODE_USE_OPENAI: process.env.CLAUDE_CODE_USE_OPENAI,
CLAUDE_CODE_USE_BEDROCK: process.env.CLAUDE_CODE_USE_BEDROCK,
CLAUDE_CODE_USE_VERTEX: process.env.CLAUDE_CODE_USE_VERTEX,
CLAUDE_CODE_USE_FOUNDRY: process.env.CLAUDE_CODE_USE_FOUNDRY,
}
afterEach(() => {
process.env.CLAUDE_CODE_USE_GEMINI = originalEnv.CLAUDE_CODE_USE_GEMINI
process.env.CLAUDE_CODE_USE_OPENAI = originalEnv.CLAUDE_CODE_USE_OPENAI
process.env.CLAUDE_CODE_USE_BEDROCK = originalEnv.CLAUDE_CODE_USE_BEDROCK
process.env.CLAUDE_CODE_USE_VERTEX = originalEnv.CLAUDE_CODE_USE_VERTEX
process.env.CLAUDE_CODE_USE_FOUNDRY = originalEnv.CLAUDE_CODE_USE_FOUNDRY
})
function clearProviderEnv(): void {
delete process.env.CLAUDE_CODE_USE_GEMINI
delete process.env.CLAUDE_CODE_USE_OPENAI
delete process.env.CLAUDE_CODE_USE_BEDROCK
delete process.env.CLAUDE_CODE_USE_VERTEX
delete process.env.CLAUDE_CODE_USE_FOUNDRY
}
test('first-party provider keeps Anthropic account setup flow enabled', () => {
clearProviderEnv()
expect(getAPIProvider()).toBe('firstParty')
expect(usesAnthropicAccountFlow()).toBe(true)
})
test.each([
['CLAUDE_CODE_USE_OPENAI', 'openai'],
['CLAUDE_CODE_USE_GEMINI', 'gemini'],
['CLAUDE_CODE_USE_BEDROCK', 'bedrock'],
['CLAUDE_CODE_USE_VERTEX', 'vertex'],
['CLAUDE_CODE_USE_FOUNDRY', 'foundry'],
] as const)(
'%s disables Anthropic account setup flow',
(envKey, provider) => {
clearProviderEnv()
process.env[envKey] = '1'
expect(getAPIProvider()).toBe(provider)
expect(usesAnthropicAccountFlow()).toBe(false)
},
)

View File

@@ -17,6 +17,10 @@ export function getAPIProvider(): APIProvider {
: 'firstParty' : 'firstParty'
} }
export function usesAnthropicAccountFlow(): boolean {
return getAPIProvider() === 'firstParty'
}
export function getAPIProviderForStatsig(): AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS { export function getAPIProviderForStatsig(): AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS {
return getAPIProvider() as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS return getAPIProvider() as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS
} }