refactor(runtime): finalize codex native-only config contract
This commit is contained in:
parent
ee7deb15f7
commit
1794e5be4e
10 changed files with 18 additions and 75 deletions
|
|
@ -525,25 +525,7 @@ function validateProviderConnectionsSection(
|
||||||
const codexUpdate: Partial<ProviderConnectionsConfig['codex']> = {};
|
const codexUpdate: Partial<ProviderConnectionsConfig['codex']> = {};
|
||||||
|
|
||||||
for (const [connectionKey, connectionValue] of Object.entries(value)) {
|
for (const [connectionKey, connectionValue] of Object.entries(value)) {
|
||||||
if (connectionKey === 'apiKeyBetaEnabled') {
|
if (connectionKey === 'apiKeyBetaEnabled' || connectionKey === 'authMode') {
|
||||||
if (typeof connectionValue !== 'boolean') {
|
|
||||||
return {
|
|
||||||
valid: false,
|
|
||||||
error: 'providerConnections.codex.apiKeyBetaEnabled must be a boolean',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
codexUpdate.apiKeyBetaEnabled = connectionValue;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connectionKey === 'authMode') {
|
|
||||||
if (connectionValue !== 'oauth' && connectionValue !== 'api_key') {
|
|
||||||
return {
|
|
||||||
valid: false,
|
|
||||||
error: 'providerConnections.codex.authMode must be one of: oauth, api_key',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
codexUpdate.authMode = connectionValue;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -232,16 +232,12 @@ export interface RuntimeConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ProviderConnectionAuthMode = 'auto' | 'oauth' | 'api_key';
|
export type ProviderConnectionAuthMode = 'auto' | 'oauth' | 'api_key';
|
||||||
export type CodexProviderConnectionAuthMode = Exclude<ProviderConnectionAuthMode, 'auto'>;
|
|
||||||
|
|
||||||
export interface ProviderConnectionsConfig {
|
export interface ProviderConnectionsConfig {
|
||||||
anthropic: {
|
anthropic: {
|
||||||
authMode: ProviderConnectionAuthMode;
|
authMode: ProviderConnectionAuthMode;
|
||||||
};
|
};
|
||||||
codex: {
|
codex: Record<string, never>;
|
||||||
apiKeyBetaEnabled: boolean;
|
|
||||||
authMode: CodexProviderConnectionAuthMode;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DisplayConfig {
|
export interface DisplayConfig {
|
||||||
|
|
@ -335,10 +331,7 @@ const DEFAULT_CONFIG: AppConfig = {
|
||||||
anthropic: {
|
anthropic: {
|
||||||
authMode: 'auto',
|
authMode: 'auto',
|
||||||
},
|
},
|
||||||
codex: {
|
codex: {},
|
||||||
apiKeyBetaEnabled: false,
|
|
||||||
authMode: 'oauth',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
runtime: {
|
runtime: {
|
||||||
providerBackends: {
|
providerBackends: {
|
||||||
|
|
@ -567,10 +560,7 @@ export class ConfigManager {
|
||||||
...DEFAULT_CONFIG.providerConnections.anthropic,
|
...DEFAULT_CONFIG.providerConnections.anthropic,
|
||||||
...(loaded.providerConnections?.anthropic ?? {}),
|
...(loaded.providerConnections?.anthropic ?? {}),
|
||||||
},
|
},
|
||||||
codex: {
|
codex: {},
|
||||||
...DEFAULT_CONFIG.providerConnections.codex,
|
|
||||||
...(loaded.providerConnections?.codex ?? {}),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
runtime: {
|
runtime: {
|
||||||
providerBackends: {
|
providerBackends: {
|
||||||
|
|
|
||||||
|
|
@ -290,8 +290,6 @@ export class ProviderConnectionService {
|
||||||
...capabilities,
|
...capabilities,
|
||||||
configurableAuthModes,
|
configurableAuthModes,
|
||||||
configuredAuthMode,
|
configuredAuthMode,
|
||||||
apiKeyBetaAvailable: providerId === 'codex' ? undefined : undefined,
|
|
||||||
apiKeyBetaEnabled: providerId === 'codex' ? undefined : undefined,
|
|
||||||
apiKeyConfigured: Boolean(storedApiKey?.value.trim() || externalCredential?.value.trim()),
|
apiKeyConfigured: Boolean(storedApiKey?.value.trim() || externalCredential?.value.trim()),
|
||||||
apiKeySource: storedApiKey?.value.trim()
|
apiKeySource: storedApiKey?.value.trim()
|
||||||
? 'stored'
|
? 'stored'
|
||||||
|
|
|
||||||
|
|
@ -332,10 +332,7 @@ export function useSettingsHandlers({
|
||||||
anthropic: {
|
anthropic: {
|
||||||
authMode: 'auto',
|
authMode: 'auto',
|
||||||
},
|
},
|
||||||
codex: {
|
codex: {},
|
||||||
apiKeyBetaEnabled: false,
|
|
||||||
authMode: 'oauth',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
runtime: {
|
runtime: {
|
||||||
providerBackends: {
|
providerBackends: {
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,6 @@ export interface CliProviderConnectionInfo {
|
||||||
supportsApiKey: boolean;
|
supportsApiKey: boolean;
|
||||||
configurableAuthModes: CliProviderAuthMode[];
|
configurableAuthModes: CliProviderAuthMode[];
|
||||||
configuredAuthMode: CliProviderAuthMode | null;
|
configuredAuthMode: CliProviderAuthMode | null;
|
||||||
apiKeyBetaAvailable?: boolean;
|
|
||||||
apiKeyBetaEnabled?: boolean;
|
|
||||||
apiKeyConfigured: boolean;
|
apiKeyConfigured: boolean;
|
||||||
apiKeySource: 'stored' | 'environment' | null;
|
apiKeySource: 'stored' | 'environment' | null;
|
||||||
apiKeySourceLabel?: string | null;
|
apiKeySourceLabel?: string | null;
|
||||||
|
|
|
||||||
|
|
@ -328,10 +328,7 @@ export interface AppConfig {
|
||||||
anthropic: {
|
anthropic: {
|
||||||
authMode: 'auto' | 'oauth' | 'api_key';
|
authMode: 'auto' | 'oauth' | 'api_key';
|
||||||
};
|
};
|
||||||
codex: {
|
codex: Record<string, never>;
|
||||||
apiKeyBetaEnabled: boolean;
|
|
||||||
authMode: 'oauth' | 'api_key';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
/** Runtime backend preferences for app-launched agent_teams_orchestrator sessions */
|
/** Runtime backend preferences for app-launched agent_teams_orchestrator sessions */
|
||||||
runtime: {
|
runtime: {
|
||||||
|
|
|
||||||
|
|
@ -208,7 +208,7 @@ describe('configValidation', () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('accepts Codex provider connection beta updates', () => {
|
it('normalizes legacy Codex provider connection updates to the native-only config shape', () => {
|
||||||
const result = validateConfigUpdatePayload('providerConnections', {
|
const result = validateConfigUpdatePayload('providerConnections', {
|
||||||
codex: {
|
codex: {
|
||||||
apiKeyBetaEnabled: true,
|
apiKeyBetaEnabled: true,
|
||||||
|
|
@ -219,24 +219,23 @@ describe('configValidation', () => {
|
||||||
expect(result.valid).toBe(true);
|
expect(result.valid).toBe(true);
|
||||||
if (result.valid) {
|
if (result.valid) {
|
||||||
expect(result.data).toEqual({
|
expect(result.data).toEqual({
|
||||||
codex: {
|
codex: {},
|
||||||
apiKeyBetaEnabled: true,
|
|
||||||
authMode: 'api_key',
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('rejects invalid Codex auth modes in providerConnections', () => {
|
it('drops unsupported legacy Codex auth modes during providerConnections migration', () => {
|
||||||
const result = validateConfigUpdatePayload('providerConnections', {
|
const result = validateConfigUpdatePayload('providerConnections', {
|
||||||
codex: {
|
codex: {
|
||||||
authMode: 'auto',
|
authMode: 'auto',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result.valid).toBe(false);
|
expect(result.valid).toBe(true);
|
||||||
if (!result.valid) {
|
if (result.valid) {
|
||||||
expect(result.error).toContain('providerConnections.codex.authMode');
|
expect(result.data).toEqual({
|
||||||
|
codex: {},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,7 @@ describe('ProviderConnectionService', () => {
|
||||||
anthropic: {
|
anthropic: {
|
||||||
authMode,
|
authMode,
|
||||||
},
|
},
|
||||||
codex: {
|
codex: {},
|
||||||
apiKeyBetaEnabled: false,
|
|
||||||
authMode: 'oauth' as const,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
runtime: {
|
runtime: {
|
||||||
providerBackends: {
|
providerBackends: {
|
||||||
|
|
@ -183,8 +180,6 @@ describe('ProviderConnectionService', () => {
|
||||||
apiKeySource: null,
|
apiKeySource: null,
|
||||||
apiKeySourceLabel: null,
|
apiKeySourceLabel: null,
|
||||||
});
|
});
|
||||||
expect(info.apiKeyBetaAvailable).toBeUndefined();
|
|
||||||
expect(info.apiKeyBetaEnabled).toBeUndefined();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('mirrors a stored OpenAI key into CODEX_API_KEY for native Codex launches', async () => {
|
it('mirrors a stored OpenAI key into CODEX_API_KEY for native Codex launches', async () => {
|
||||||
|
|
|
||||||
|
|
@ -179,8 +179,6 @@ function createApiKeyMisconfiguredProvider(
|
||||||
configurableAuthModes:
|
configurableAuthModes:
|
||||||
providerId === 'anthropic' ? ['auto', 'oauth', 'api_key'] : [],
|
providerId === 'anthropic' ? ['auto', 'oauth', 'api_key'] : [],
|
||||||
configuredAuthMode: providerId === 'anthropic' ? 'api_key' : null,
|
configuredAuthMode: providerId === 'anthropic' ? 'api_key' : null,
|
||||||
apiKeyBetaAvailable: undefined,
|
|
||||||
apiKeyBetaEnabled: undefined,
|
|
||||||
apiKeyConfigured: false,
|
apiKeyConfigured: false,
|
||||||
apiKeySource: null,
|
apiKeySource: null,
|
||||||
apiKeySourceLabel: null,
|
apiKeySourceLabel: null,
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,7 @@ interface StoreState {
|
||||||
anthropic: {
|
anthropic: {
|
||||||
authMode: 'auto' | 'oauth' | 'api_key';
|
authMode: 'auto' | 'oauth' | 'api_key';
|
||||||
};
|
};
|
||||||
codex: {
|
codex: Record<string, never>;
|
||||||
apiKeyBetaEnabled: boolean;
|
|
||||||
authMode: 'oauth' | 'api_key';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
apiKeys: {
|
apiKeys: {
|
||||||
|
|
@ -205,8 +202,6 @@ function createCodexProvider(
|
||||||
supportsApiKey: true,
|
supportsApiKey: true,
|
||||||
configurableAuthModes: [],
|
configurableAuthModes: [],
|
||||||
configuredAuthMode: null,
|
configuredAuthMode: null,
|
||||||
apiKeyBetaAvailable: undefined,
|
|
||||||
apiKeyBetaEnabled: undefined,
|
|
||||||
apiKeyConfigured: overrides?.apiKeyConfigured ?? false,
|
apiKeyConfigured: overrides?.apiKeyConfigured ?? false,
|
||||||
apiKeySource: overrides?.apiKeySource ?? null,
|
apiKeySource: overrides?.apiKeySource ?? null,
|
||||||
apiKeySourceLabel: overrides?.apiKeySourceLabel ?? null,
|
apiKeySourceLabel: overrides?.apiKeySourceLabel ?? null,
|
||||||
|
|
@ -323,10 +318,7 @@ describe('ProviderRuntimeSettingsDialog', () => {
|
||||||
anthropic: {
|
anthropic: {
|
||||||
authMode: 'auto',
|
authMode: 'auto',
|
||||||
},
|
},
|
||||||
codex: {
|
codex: {},
|
||||||
apiKeyBetaEnabled: false,
|
|
||||||
authMode: 'oauth',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
storeState.apiKeys = [];
|
storeState.apiKeys = [];
|
||||||
|
|
@ -348,10 +340,7 @@ describe('ProviderRuntimeSettingsDialog', () => {
|
||||||
...storeState.appConfig.providerConnections.anthropic,
|
...storeState.appConfig.providerConnections.anthropic,
|
||||||
...(nextProviderConnections.anthropic ?? {}),
|
...(nextProviderConnections.anthropic ?? {}),
|
||||||
},
|
},
|
||||||
codex: {
|
codex: {},
|
||||||
...storeState.appConfig.providerConnections.codex,
|
|
||||||
...(nextProviderConnections.codex ?? {}),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue