From e6e9a089840623865cc1fa8fe4680ee684c9a011 Mon Sep 17 00:00:00 2001 From: Fayzan Ahmed Date: Tue, 29 Sep 2026 10:36:01 +0000 Subject: [PATCH] Drop conflicting auth keys from the Codex requesty provider on configure Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- internal/harnesses/codex.go | 13 ++++++++++ internal/harnesses/codex_test.go | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/internal/harnesses/codex.go b/internal/harnesses/codex.go index a2d69fc..d09e986 100644 --- a/internal/harnesses/codex.go +++ b/internal/harnesses/codex.go @@ -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"` @@ -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) + } + } + } + if err := backupAndWriteConfigFileAsTOML(configPath, &config); err != nil { return fmt.Errorf("failed to write config file: %w", err) } diff --git a/internal/harnesses/codex_test.go b/internal/harnesses/codex_test.go index e45341c..f2c3f61 100644 --- a/internal/harnesses/codex_test.go +++ b/internal/harnesses/codex_test.go @@ -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]) +}