fix(settings): improve codex CLI auth mode switching to preserve auth.json keys
- Patch only `OPENAI_API_KEY` and `auth_mode` in auth.json when switching auth modes, instead of resetting the entire file - Clean up `OPENAI_BASE_URL` from env when codex loads in official subscription mode - Hide API URL and API Key inputs when model provider mode is selected Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1782,7 +1782,7 @@ function ensureCodexProviderDefaults(
|
|||||||
|
|
||||||
function patchCodexAuthJsonText(
|
function patchCodexAuthJsonText(
|
||||||
authJsonText: string,
|
authJsonText: string,
|
||||||
patch: { apiKey?: string }
|
patch: { apiKey?: string; authMode?: "chatgpt" | null }
|
||||||
): {
|
): {
|
||||||
authJsonText: string
|
authJsonText: string
|
||||||
recoveredFromInvalid: boolean
|
recoveredFromInvalid: boolean
|
||||||
@@ -1801,6 +1801,14 @@ function patchCodexAuthJsonText(
|
|||||||
delete authObject.API_KEY
|
delete authObject.API_KEY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ("authMode" in patch) {
|
||||||
|
if (patch.authMode === "chatgpt") {
|
||||||
|
authObject.auth_mode = "chatgpt"
|
||||||
|
authObject.OPENAI_API_KEY = null
|
||||||
|
} else {
|
||||||
|
delete authObject.auth_mode
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
authJsonText:
|
authJsonText:
|
||||||
Object.keys(authObject).length === 0
|
Object.keys(authObject).length === 0
|
||||||
@@ -2082,9 +2090,24 @@ function buildAgentDraft(agent: AcpAgentInfo): AgentDraft {
|
|||||||
openCodeAuthJsonText
|
openCodeAuthJsonText
|
||||||
)
|
)
|
||||||
const clineImportant = extractClineImportantValues(configText)
|
const clineImportant = extractClineImportantValues(configText)
|
||||||
|
const codexAuthMode: CodexAuthMode =
|
||||||
|
agent.agent_type === "codex" && agent.model_provider_id != null
|
||||||
|
? "model_provider"
|
||||||
|
: agent.agent_type === "codex"
|
||||||
|
? inferCodexAuthMode(codexAuthJsonText)
|
||||||
|
: "api_key"
|
||||||
|
const rawEnvText = envMapToText(agent.env)
|
||||||
|
// When codex is in official subscription mode, clean up API keys/URLs from env
|
||||||
|
const envText =
|
||||||
|
agent.agent_type === "codex" && codexAuthMode === "chatgpt_subscription"
|
||||||
|
? patchEnvText(rawEnvText, {
|
||||||
|
OPENAI_API_KEY: "",
|
||||||
|
OPENAI_BASE_URL: "",
|
||||||
|
})
|
||||||
|
: rawEnvText
|
||||||
return {
|
return {
|
||||||
enabled: agent.enabled,
|
enabled: agent.enabled,
|
||||||
envText: envMapToText(agent.env),
|
envText,
|
||||||
configText,
|
configText,
|
||||||
apiBaseUrl:
|
apiBaseUrl:
|
||||||
agent.agent_type === "codex"
|
agent.agent_type === "codex"
|
||||||
@@ -2123,12 +2146,7 @@ function buildAgentDraft(agent: AcpAgentInfo): AgentDraft {
|
|||||||
googleCloudProject: geminiImportant.googleCloudProject,
|
googleCloudProject: geminiImportant.googleCloudProject,
|
||||||
googleCloudLocation: geminiImportant.googleCloudLocation,
|
googleCloudLocation: geminiImportant.googleCloudLocation,
|
||||||
googleApplicationCredentials: geminiImportant.googleApplicationCredentials,
|
googleApplicationCredentials: geminiImportant.googleApplicationCredentials,
|
||||||
codexAuthMode:
|
codexAuthMode,
|
||||||
agent.agent_type === "codex" && agent.model_provider_id != null
|
|
||||||
? "model_provider"
|
|
||||||
: agent.agent_type === "codex"
|
|
||||||
? inferCodexAuthMode(codexAuthJsonText)
|
|
||||||
: "api_key",
|
|
||||||
codexModelProvider: codexImportant.modelProvider,
|
codexModelProvider: codexImportant.modelProvider,
|
||||||
codexProviderOptions: codexImportant.providerOptions,
|
codexProviderOptions: codexImportant.providerOptions,
|
||||||
codexReasoningEffort: codexImportant.reasoningEffort,
|
codexReasoningEffort: codexImportant.reasoningEffort,
|
||||||
@@ -3472,9 +3490,11 @@ export function AcpAgentSettings() {
|
|||||||
configText: nextConfigJson.configText,
|
configText: nextConfigJson.configText,
|
||||||
}))
|
}))
|
||||||
} else if (agentType === "codex") {
|
} else if (agentType === "codex") {
|
||||||
const nextAuthJsonText = apiKey
|
const nextAuthPatch = patchCodexAuthJsonText(
|
||||||
? JSON.stringify({ OPENAI_API_KEY: apiKey }, null, 2)
|
selectedDraft.codexAuthJsonText,
|
||||||
: "{}"
|
{ apiKey, authMode: null }
|
||||||
|
)
|
||||||
|
const nextAuthJsonText = nextAuthPatch.authJsonText
|
||||||
const nextConfigTomlText = patchCodexConfigTomlText(
|
const nextConfigTomlText = patchCodexConfigTomlText(
|
||||||
selectedDraft.codexConfigTomlText,
|
selectedDraft.codexConfigTomlText,
|
||||||
{
|
{
|
||||||
@@ -4344,8 +4364,12 @@ export function AcpAgentSettings() {
|
|||||||
return
|
return
|
||||||
|
|
||||||
if (nextMode === "chatgpt_subscription") {
|
if (nextMode === "chatgpt_subscription") {
|
||||||
// Official subscription: clear API URL/Key from env, remove model_provider config from toml
|
// Official subscription: set auth_mode to chatgpt, OPENAI_API_KEY to null
|
||||||
const nextAuthJsonText = "{}"
|
const nextAuth = patchCodexAuthJsonText(
|
||||||
|
selectedDraft.codexAuthJsonText,
|
||||||
|
{ authMode: "chatgpt" }
|
||||||
|
)
|
||||||
|
const nextAuthJsonText = nextAuth.authJsonText
|
||||||
let nextConfigTomlText = updateTomlRootStringKey(
|
let nextConfigTomlText = updateTomlRootStringKey(
|
||||||
selectedDraft.codexConfigTomlText,
|
selectedDraft.codexConfigTomlText,
|
||||||
"model_provider",
|
"model_provider",
|
||||||
@@ -4385,14 +4409,11 @@ export function AcpAgentSettings() {
|
|||||||
selectedDraft.codexConfigTomlText,
|
selectedDraft.codexConfigTomlText,
|
||||||
{ modelProvider: CODEX_DEFAULT_MODEL_PROVIDER }
|
{ modelProvider: CODEX_DEFAULT_MODEL_PROVIDER }
|
||||||
)
|
)
|
||||||
const nextAuthJsonText =
|
const nextAuthPatch = patchCodexAuthJsonText(
|
||||||
nextMode === "api_key"
|
selectedDraft.codexAuthJsonText,
|
||||||
? JSON.stringify(
|
{ authMode: null }
|
||||||
{ OPENAI_API_KEY: selectedDraft.apiKey || "" },
|
)
|
||||||
null,
|
const nextAuthJsonText = nextAuthPatch.authJsonText
|
||||||
2
|
|
||||||
)
|
|
||||||
: selectedDraft.codexAuthJsonText
|
|
||||||
const synced = extractCodexImportantValues(
|
const synced = extractCodexImportantValues(
|
||||||
nextAuthJsonText,
|
nextAuthJsonText,
|
||||||
nextConfigTomlText
|
nextConfigTomlText
|
||||||
@@ -4940,17 +4961,13 @@ export function AcpAgentSettings() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{(selectedDraft.codexAuthMode === "api_key" ||
|
{selectedDraft.codexAuthMode === "api_key" && (
|
||||||
selectedDraft.codexAuthMode === "model_provider") && (
|
|
||||||
<div className="space-y-1.5">
|
<div className="space-y-1.5">
|
||||||
<label className="text-[11px] text-muted-foreground">
|
<label className="text-[11px] text-muted-foreground">
|
||||||
API URL
|
API URL
|
||||||
</label>
|
</label>
|
||||||
<Input
|
<Input
|
||||||
value={selectedDraft.apiBaseUrl}
|
value={selectedDraft.apiBaseUrl}
|
||||||
readOnly={
|
|
||||||
selectedDraft.codexAuthMode === "model_provider"
|
|
||||||
}
|
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
handleCodexImportantConfigChange(
|
handleCodexImportantConfigChange(
|
||||||
"apiBaseUrl",
|
"apiBaseUrl",
|
||||||
@@ -4962,8 +4979,7 @@ export function AcpAgentSettings() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{(selectedDraft.codexAuthMode === "api_key" ||
|
{selectedDraft.codexAuthMode === "api_key" && (
|
||||||
selectedDraft.codexAuthMode === "model_provider") && (
|
|
||||||
<div className="space-y-1.5">
|
<div className="space-y-1.5">
|
||||||
<label className="text-[11px] text-muted-foreground">
|
<label className="text-[11px] text-muted-foreground">
|
||||||
API Key
|
API Key
|
||||||
@@ -4976,9 +4992,6 @@ export function AcpAgentSettings() {
|
|||||||
: "password"
|
: "password"
|
||||||
}
|
}
|
||||||
value={selectedDraft.apiKey}
|
value={selectedDraft.apiKey}
|
||||||
readOnly={
|
|
||||||
selectedDraft.codexAuthMode === "model_provider"
|
|
||||||
}
|
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
handleCodexImportantConfigChange(
|
handleCodexImportantConfigChange(
|
||||||
"apiKey",
|
"apiKey",
|
||||||
|
|||||||
Reference in New Issue
Block a user