Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions internal/harnesses/codex.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ const (
codexModelProvider = "requesty"
)

// codexProviderAuthConflicts are provider keys Codex refuses alongside
// `auth`.
var codexProviderAuthConflicts = []string{"env_key", "experimental_bearer_token", "requires_openai_auth"}

type codexConfig struct {
Model string `toml:"model"`
ModelProvider string `toml:"model_provider"`
Expand Down Expand Up @@ -154,6 +158,15 @@ func (c *CodexHarness) configureMerge(opts ConfigureOptions) error {
return fmt.Errorf("failed to merge config file: %w", err)
}

// Remove auth methods Codex refuses alongside our command-based auth.
if providers, ok := config["model_providers"].(map[string]any); ok {
if provider, ok := providers[codexModelProvider].(map[string]any); ok {
for _, key := range codexProviderAuthConflicts {
delete(provider, key)
}
}
}
Comment thread
lavicosa marked this conversation as resolved.

if err := backupAndWriteConfigFileAsTOML(configPath, &config); err != nil {
return fmt.Errorf("failed to write config file: %w", err)
}
Expand Down
43 changes: 43 additions & 0 deletions internal/harnesses/codex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,46 @@ func TestTomlStringQuotesForCodexOverrides(t *testing.T) {
assert.Equal(t, value, parsed.Value)
}
}

func TestCodexHarnessConfigureMergeDropsConflictingProviderAuth(t *testing.T) {
cfg := config.Config{
Name: "work",
RouterBaseURL: "https://router.requesty.ai",
APIKey: "my-api-key",
}
configDir := t.TempDir()
configPath := filepath.Join(configDir, "config.toml")
require.NoError(t, os.WriteFile(configPath, []byte(`
model_provider = "requesty"

[model_providers.requesty]
name = "Requesty"
base_url = "https://router.requesty.ai/v1"
env_key = "OPENAI_API_KEY"
experimental_bearer_token = "rqsty-sk-old"
requires_openai_auth = true
custom_provider_setting = "keep-me"
`), 0o600))
harness := newCodexHarness(cfg, configDir)

require.NoError(t, harness.Configure(ConfigureOptions{
Model: "openai-responses/gpt-5.5",
}))

configBytes, err := os.ReadFile(configPath)
require.NoError(t, err)
var parsedConfig map[string]any
require.NoError(t, toml.Unmarshal(configBytes, &parsedConfig))
assert.Equal(t, map[string]any{
"name": "Requesty",
"base_url": "https://router.requesty.ai/v1",
"custom_provider_setting": "keep-me",
"http_headers": map[string]any{
"X-Title": "OpenAI Codex",
},
"auth": map[string]any{
"command": "requesty",
"args": []any{"auth", "token", "--profile", "work"},
},
}, parsedConfig["model_providers"].(map[string]any)[codexModelProvider])
}
Loading