Files
open-design/apps/daemon/tests/codex-provider-env-key.test.ts
Abhishek SarkarandGitHub 409c123bba fix(daemon): stop local CLI auth probes misclassifying valid auth (#4632)
Two local-CLI auth-probe edge cases (#4456, follow-up to #4453) reported a
working CLI as unauthenticated:

1. Codex custom providers authenticate via a provider-specific `env_key`
   (e.g. AZURE_OPENAI_API_KEY) declared in ~/.codex/config.toml, but the
   probe's API-key short-circuit only checked CODEX_API_KEY / OPENAI_API_KEY.
   A non-zero `codex login status` (a ChatGPT/OpenAI-login check) then
   surfaced authStatus "missing" for valid custom-provider installs. The
   probe now resolves the selected provider's env_key from config.toml and
   treats its presence as satisfying auth.

2. Local profiles that inherit a base adapter's authProbe run under the
   profile id, so the classifier (keyed off the agent id) fell through to
   the generic text classifier instead of the base adapter's tailored
   parser. For an inherited Claude probe, healthy output
   (`{"authenticated": true}`) then matched the generic "authenticated"
   regex and was misread as an auth failure. The inherited probe now carries
   `classifierAgentId`, and the probe uses it for both tailored classification
   and the API-key short-circuit.

Add regression coverage: unit tests for the Codex provider env_key extractor
and probe-level tests for both cases (including the generic-classifier
misread the fix prevents).
2026-07-05 14:38:27 +00:00

85 lines
2.9 KiB
TypeScript

// Regression coverage for #4456 (Case 1): the Codex auth probe must recognize
// a working custom provider whose API key lives in a provider-specific
// `env_key` (e.g. AZURE_OPENAI_API_KEY) declared in ~/.codex/config.toml, not
// just CODEX_API_KEY / OPENAI_API_KEY. `extractCodexProviderEnvKey` resolves
// the selected provider's `env_key` from the config text.
import { describe, expect, it } from 'vitest';
import { extractCodexProviderEnvKey } from '../src/codex-config-normalize.js';
describe('extractCodexProviderEnvKey', () => {
it('resolves the selected custom provider env_key', () => {
const toml = [
'model_provider = "azure"',
'',
'[model_providers.azure]',
'base_url = "https://example.openai.azure.com/openai/v1"',
'env_key = "AZURE_OPENAI_API_KEY"',
].join('\n');
expect(extractCodexProviderEnvKey(toml)).toBe('AZURE_OPENAI_API_KEY');
});
it('picks the env_key of the SELECTED provider among several', () => {
const toml = [
'model_provider = "azure"',
'[model_providers.openai]',
'env_key = "OPENAI_API_KEY"',
'[model_providers.azure]',
'env_key = "AZURE_OPENAI_API_KEY"',
].join('\n');
expect(extractCodexProviderEnvKey(toml)).toBe('AZURE_OPENAI_API_KEY');
});
it('honors single quotes and trailing comments', () => {
const toml = [
"model_provider = 'azure' # selected",
'[model_providers.azure]',
"env_key = 'AZURE_OPENAI_API_KEY' # the key var",
].join('\n');
expect(extractCodexProviderEnvKey(toml)).toBe('AZURE_OPENAI_API_KEY');
});
it('handles a quoted provider table header', () => {
const toml = [
'model_provider = "azure"',
'[model_providers."azure"]',
'env_key = "AZURE_OPENAI_API_KEY"',
].join('\n');
expect(extractCodexProviderEnvKey(toml)).toBe('AZURE_OPENAI_API_KEY');
});
it('returns null when no provider is selected', () => {
const toml = [
'[model_providers.azure]',
'env_key = "AZURE_OPENAI_API_KEY"',
].join('\n');
expect(extractCodexProviderEnvKey(toml)).toBeNull();
});
it('returns null when the selected provider declares no env_key', () => {
const toml = [
'model_provider = "azure"',
'[model_providers.azure]',
'base_url = "https://example.openai.azure.com/openai/v1"',
].join('\n');
expect(extractCodexProviderEnvKey(toml)).toBeNull();
});
it('does not leak an env_key from a non-selected provider table', () => {
const toml = [
'model_provider = "azure"',
'[model_providers.openai]',
'env_key = "OPENAI_API_KEY"',
'[model_providers.azure]',
'base_url = "https://example.openai.azure.com/openai/v1"',
].join('\n');
expect(extractCodexProviderEnvKey(toml)).toBeNull();
});
it('returns null for empty or non-provider config', () => {
expect(extractCodexProviderEnvKey('')).toBeNull();
expect(extractCodexProviderEnvKey('model = "gpt-5"\n')).toBeNull();
});
});