Skip to content

Commit 5d63945

Browse files
committed
feat(openai-native-codex): remove service tier logic; stop forcing minimal effort; add request timeout; improve auth.json error guidance; update ChatGPT link; clear reasoningEffort on model change\n\n- Remove service_tier handling entirely for Codex (server decides tier)\n- Do not auto-default GPT-5 to minimal for Codex; use model/user defaults only\n- Add AbortController using getApiRequestTimeout() to prevent hanging requests\n- Improve auth.json error messages with Codex CLI guidance\n- Update settings link to chatgpt.com\n- Clear reasoningEffort on model change for Codex like native OpenAI
1 parent 4ba05da commit 5d63945

File tree

4 files changed

+26
-23
lines changed

4 files changed

+26
-23
lines changed

src/api/providers/openai-native-codex.ts

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { ApiStream, ApiStreamUsageChunk } from "../transform/stream"
99
import { getModelParams } from "../transform/model-params"
1010
// Provider prompt content as a TS string module (no loader required)
1111
import codexPromptContent, { overridePrompt } from "./openai-native-codex.prompt"
12+
import { getApiRequestTimeout } from "./utils/timeout-config"
1213

1314
import {
1415
type ModelInfo,
@@ -110,14 +111,18 @@ export class OpenAiNativeCodexHandler extends BaseProvider {
110111
try {
111112
raw = await fs.readFile(explicitPath, "utf8")
112113
} catch (e: any) {
113-
throw new Error(`Failed to load ChatGPT OAuth credentials at ${explicitPath}: ${e?.message || e}`)
114+
throw new Error(
115+
`Failed to load ChatGPT OAuth credentials at ${explicitPath}: ${e?.message || e}. Tip: authenticate with the Codex CLI (e.g., "codex login") to create auth.json.`,
116+
)
114117
}
115118

116119
let j: any
117120
try {
118121
j = JSON.parse(raw)
119122
} catch (e: any) {
120-
throw new Error(`Failed to parse ChatGPT OAuth credentials JSON at ${explicitPath}: ${e?.message || e}`)
123+
throw new Error(
124+
`Failed to parse ChatGPT OAuth credentials JSON at ${explicitPath}: ${e?.message || e}. Tip: ensure the file is valid JSON or re-authenticate with "codex login" to regenerate it.`,
125+
)
121126
}
122127

123128
const tokens = (j?.tokens as any) || {}
@@ -263,13 +268,7 @@ export class OpenAiNativeCodexHandler extends BaseProvider {
263268
// - Regular "gpt-5" should default to minimal reasoning unless explicitly overridden in settings.
264269
// - The "gpt-5-codex" variant should NOT force minimal; use provided/default effort.
265270
let effectiveEffort: ReasoningEffortWithMinimal | undefined = reasoningEffort
266-
const explicitEffortProvided = typeof (this.options.reasoningEffort as any) === "string"
267-
if (!explicitEffortProvided && model.id === "gpt-5") {
268-
effectiveEffort = "minimal"
269-
}
270271

271-
const requestedTier = (this.options.openAiNativeServiceTier as ServiceTier | undefined) || undefined
272-
const allowedTierNames = new Set(model.info.tiers?.map((t) => t.name).filter(Boolean) || [])
273272
const body: any = {
274273
model: model.id,
275274
input: formattedInput,
@@ -286,9 +285,6 @@ export class OpenAiNativeCodexHandler extends BaseProvider {
286285
}),
287286
// ChatGPT codex/responses does not support previous_response_id (stateless).
288287
// Preserve continuity by sending curated prior items in `input`.
289-
...(requestedTier && (requestedTier === "default" || allowedTierNames.has(requestedTier))
290-
? { service_tier: requestedTier }
291-
: {}),
292288
}
293289
if (model.info.supportsVerbosity === true) {
294290
body.text = { verbosity: (verbosity || "medium") as VerbosityLevel }
@@ -307,11 +303,16 @@ export class OpenAiNativeCodexHandler extends BaseProvider {
307303
}
308304
if (this.chatgptAccountId) headers["chatgpt-account-id"] = this.chatgptAccountId
309305

306+
let timeoutId: ReturnType<typeof setTimeout> | undefined
310307
try {
308+
const timeoutMs = getApiRequestTimeout()
309+
const controller = new AbortController()
310+
timeoutId = timeoutMs > 0 ? setTimeout(() => controller.abort(), timeoutMs) : undefined
311311
const response = await fetch(url, {
312312
method: "POST",
313313
headers,
314314
body: JSON.stringify(requestBody),
315+
signal: controller.signal,
315316
})
316317

317318
if (!response.ok) {
@@ -468,7 +469,12 @@ export class OpenAiNativeCodexHandler extends BaseProvider {
468469
} catch (err) {
469470
throw err as Error
470471
} finally {
471-
// no-op
472+
// Clear timeout if set
473+
try {
474+
if (typeof timeoutId !== "undefined") {
475+
clearTimeout(timeoutId as any)
476+
}
477+
} catch {}
472478
}
473479
}
474480
}

webview-ui/src/components/settings/ApiOptions.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -704,8 +704,11 @@ const ApiOptions = ({
704704
}
705705

706706
// Clear reasoning effort when switching models to allow the new model's default to take effect
707-
// This is especially important for GPT-5 models which default to "medium"
708-
if (selectedProvider === "openai-native") {
707+
// Applies to both OpenAI Native and ChatGPT Codex providers
708+
if (
709+
selectedProvider === "openai-native" ||
710+
selectedProvider === "openai-native-codex"
711+
) {
709712
setApiConfigurationField("reasoningEffort", undefined)
710713
}
711714
}}>

webview-ui/src/components/settings/ThinkingBudget.tsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,9 @@ export const ThinkingBudget = ({ apiConfiguration, setApiConfigurationField, mod
7272
? (["minimal", ...baseEfforts] as ReasoningEffortWithMinimal[])
7373
: baseEfforts
7474

75-
// Default reasoning effort - use model's default if available
76-
// Special-case for ChatGPT Codex "gpt-5": default to "minimal" unless user overrides
75+
// Default reasoning effort - use model's default if available (no special-case overrides)
7776
const modelDefaultReasoningEffort = modelInfo?.reasoningEffort as ReasoningEffortWithMinimal | undefined
78-
const defaultReasoningEffort: ReasoningEffortWithMinimal =
79-
apiConfiguration.apiProvider === "openai-native-codex" &&
80-
selectedModelId === "gpt-5" &&
81-
isReasoningEffortSupported
82-
? "minimal"
83-
: modelDefaultReasoningEffort || "medium"
77+
const defaultReasoningEffort: ReasoningEffortWithMinimal = modelDefaultReasoningEffort || "medium"
8478
const currentReasoningEffort: ReasoningEffortWithMinimal =
8579
(apiConfiguration.reasoningEffort as ReasoningEffortWithMinimal | undefined) || defaultReasoningEffort
8680

webview-ui/src/components/settings/providers/OpenAiNativeCodex.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export const OpenAiNativeCodex: React.FC<OpenAiNativeCodexProps> = ({ apiConfigu
4343
</div>
4444

4545
<VSCodeLink
46-
href="https://chat.openai.com"
46+
href="https://chatgpt.com"
4747
className="text-vscode-textLink-foreground mt-2 inline-block text-xs">
4848
Learn more about ChatGPT
4949
</VSCodeLink>

0 commit comments

Comments
 (0)