icebear0828 Claude Opus 4.6 commited on
Commit
597668f
·
1 Parent(s): 0e1d6c8

fix: update model catalog — gpt-5.4/5.3-codex removed, gpt-5.2-codex is new flagship

Browse files

Backend dropped gpt-5.4, gpt-5.3-codex, gpt-5.3-codex-spark.
New model list: gpt-5.2-codex (default), gpt-5.2, gpt-5.1-codex-max,
gpt-5.1-codex, gpt-5.1, gpt-5-codex, gpt-5, gpt-oss-120b, gpt-oss-20b,
gpt-5.1-codex-mini, gpt-5-codex-mini.

- config/default.yaml: default model → gpt-5.2-codex
- config/models.yaml: full rewrite matching backend /codex/models response
- model-store.ts: isCodexCompatibleId() now matches gpt-oss-*,
normalizeBackendModel() handles supported_reasoning_levels + effort key
- codex-api.ts: getModels() adds ?client_version= (now required by backend)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

config/default.yaml CHANGED
@@ -9,7 +9,7 @@ client:
9
  arch: arm64
10
  chromium_version: "144"
11
  model:
12
- default: gpt-5.4
13
  default_reasoning_effort: medium
14
  default_service_tier: null
15
  suppress_desktop_directives: true
 
9
  arch: arm64
10
  chromium_version: "144"
11
  model:
12
+ default: gpt-5.2-codex
13
  default_reasoning_effort: medium
14
  default_service_tier: null
15
  suppress_desktop_directives: true
config/models.yaml CHANGED
@@ -2,294 +2,163 @@
2
  #
3
  # Sources:
4
  # 1. Static (below) — Codex-specific models (not returned by /backend-api/models)
5
- # 2. Dynamic — general ChatGPT models fetched from /backend-api/models
6
  #
7
  # Dynamic fetch merges with static; backend entries win for shared IDs.
 
 
 
8
 
9
  models:
10
- # ── GPT-5.4 ──────────────────────────────────────────────────────
11
- - id: gpt-5.4
12
- displayName: GPT-5.4
13
- description: Latest Codex flagship model
14
  isDefault: true
15
  supportedReasoningEfforts:
16
- - { reasoningEffort: none, description: "No reasoning" }
17
- - { reasoningEffort: low, description: "Fastest responses" }
18
- - { reasoningEffort: medium, description: "Balanced speed and quality" }
19
- - { reasoningEffort: high, description: "Deepest reasoning" }
20
- - { reasoningEffort: xhigh, description: "Extended deep reasoning" }
21
  defaultReasoningEffort: medium
22
  inputModalities: [text, image]
23
  supportsPersonality: true
24
  upgrade: null
25
 
26
- # ── GPT-5.3 Codex family ──────────────────────────────────────────
27
- - id: gpt-5.3-codex
28
- displayName: GPT-5.3 Codex
29
- description: Latest Codex flagship model
30
  isDefault: false
31
  supportedReasoningEfforts:
32
- - { reasoningEffort: low, description: "Fastest responses" }
33
- - { reasoningEffort: medium, description: "Balanced speed and quality" }
34
- - { reasoningEffort: high, description: "Deepest reasoning" }
 
35
  defaultReasoningEffort: medium
36
- inputModalities: [text]
37
- supportsPersonality: false
38
- upgrade: null
39
-
40
- - id: gpt-5.3-codex-high
41
- displayName: GPT-5.3 Codex High
42
- description: GPT-5.3 Codex — high reasoning tier
43
- isDefault: false
44
- supportedReasoningEfforts:
45
- - { reasoningEffort: high, description: "Deepest reasoning" }
46
- defaultReasoningEffort: high
47
- inputModalities: [text]
48
- supportsPersonality: false
49
  upgrade: null
50
 
51
- - id: gpt-5.3-codex-mid
52
- displayName: GPT-5.3 Codex Mid
53
- description: GPT-5.3 Codex — mid reasoning tier
 
54
  isDefault: false
55
  supportedReasoningEfforts:
 
56
  - { reasoningEffort: medium, description: "Balanced speed and quality" }
 
 
57
  defaultReasoningEffort: medium
58
- inputModalities: [text]
59
- supportsPersonality: false
60
- upgrade: null
61
-
62
- - id: gpt-5.3-codex-low
63
- displayName: GPT-5.3 Codex Low
64
- description: GPT-5.3 Codex — low reasoning tier (fastest)
65
- isDefault: false
66
- supportedReasoningEfforts:
67
- - { reasoningEffort: low, description: "Fastest responses" }
68
- defaultReasoningEffort: low
69
- inputModalities: [text]
70
  supportsPersonality: false
71
  upgrade: null
72
 
73
- - id: gpt-5.3-codex-max
74
- displayName: GPT-5.3 Codex Max
75
- description: GPT-5.3 Codex — extended context / deepest reasoning
76
  isDefault: false
77
  supportedReasoningEfforts:
78
  - { reasoningEffort: low, description: "Fastest responses" }
79
  - { reasoningEffort: medium, description: "Balanced speed and quality" }
80
  - { reasoningEffort: high, description: "Deepest reasoning" }
81
  defaultReasoningEffort: medium
82
- inputModalities: [text]
83
- supportsPersonality: false
84
- upgrade: null
85
-
86
- - id: gpt-5.3-codex-mini
87
- displayName: GPT-5.3 Codex Mini
88
- description: GPT-5.3 Codex — lightweight, low-latency
89
- isDefault: false
90
- supportedReasoningEfforts:
91
- - { reasoningEffort: low, description: "Fastest responses" }
92
- - { reasoningEffort: medium, description: "Balanced speed and quality" }
93
- defaultReasoningEffort: low
94
- inputModalities: [text]
95
- supportsPersonality: false
96
- upgrade: null
97
-
98
- - id: gpt-5.3-codex-spark
99
- displayName: GPT-5.3 Codex Spark
100
- description: GPT-5.3 Codex — ultra-lightweight, lowest latency
101
- isDefault: false
102
- supportedReasoningEfforts:
103
- - { reasoningEffort: minimal, description: "Minimal reasoning" }
104
- - { reasoningEffort: low, description: "Fastest responses" }
105
- defaultReasoningEffort: low
106
- inputModalities: [text]
107
  supportsPersonality: false
108
  upgrade: null
109
 
110
- # ── GPT-5.2 Codex family ──────────────────────────────────────────
111
- - id: gpt-5.2-codex
112
- displayName: GPT-5.2 Codex
113
- description: GPT-5.2 Codex flagship
114
  isDefault: false
115
  supportedReasoningEfforts:
116
  - { reasoningEffort: low, description: "Fastest responses" }
117
  - { reasoningEffort: medium, description: "Balanced speed and quality" }
118
  - { reasoningEffort: high, description: "Deepest reasoning" }
119
  defaultReasoningEffort: medium
120
- inputModalities: [text]
121
- supportsPersonality: false
122
- upgrade: null
123
-
124
- - id: gpt-5.2-codex-high
125
- displayName: GPT-5.2 Codex High
126
- description: GPT-5.2 Codex — high reasoning tier
127
- isDefault: false
128
- supportedReasoningEfforts:
129
- - { reasoningEffort: high, description: "Deepest reasoning" }
130
- defaultReasoningEffort: high
131
- inputModalities: [text]
132
  supportsPersonality: false
133
  upgrade: null
134
 
135
- - id: gpt-5.2-codex-mid
136
- displayName: GPT-5.2 Codex Mid
137
- description: GPT-5.2 Codex — mid reasoning tier
138
  isDefault: false
139
  supportedReasoningEfforts:
140
- - { reasoningEffort: medium, description: "Balanced speed and quality" }
 
141
  defaultReasoningEffort: medium
142
  inputModalities: [text]
143
  supportsPersonality: false
144
  upgrade: null
145
 
146
- - id: gpt-5.2-codex-low
147
- displayName: GPT-5.2 Codex Low
148
- description: GPT-5.2 Codex — low reasoning tier (fastest)
149
- isDefault: false
150
- supportedReasoningEfforts:
151
- - { reasoningEffort: low, description: "Fastest responses" }
152
- defaultReasoningEffort: low
153
- inputModalities: [text]
154
- supportsPersonality: false
155
- upgrade: null
156
-
157
- - id: gpt-5.2-codex-max
158
- displayName: GPT-5.2 Codex Max
159
- description: GPT-5.2 Codex — extended context / deepest reasoning
160
  isDefault: false
161
  supportedReasoningEfforts:
162
  - { reasoningEffort: low, description: "Fastest responses" }
163
  - { reasoningEffort: medium, description: "Balanced speed and quality" }
164
  - { reasoningEffort: high, description: "Deepest reasoning" }
165
  defaultReasoningEffort: medium
166
- inputModalities: [text]
167
- supportsPersonality: false
168
- upgrade: null
169
-
170
- - id: gpt-5.2-codex-mini
171
- displayName: GPT-5.2 Codex Mini
172
- description: GPT-5.2 Codex — lightweight, low-latency
173
- isDefault: false
174
- supportedReasoningEfforts:
175
- - { reasoningEffort: low, description: "Fastest responses" }
176
- - { reasoningEffort: medium, description: "Balanced speed and quality" }
177
- defaultReasoningEffort: low
178
- inputModalities: [text]
179
  supportsPersonality: false
180
  upgrade: null
181
 
182
- # ── GPT-5.1 Codex family ──────────────────────────────────────────
183
- - id: gpt-5.1-codex
184
- displayName: GPT-5.1 Codex
185
- description: GPT-5.1 Codex
186
  isDefault: false
187
  supportedReasoningEfforts:
188
- - { reasoningEffort: low, description: "Fastest responses" }
189
- - { reasoningEffort: medium, description: "Balanced speed and quality" }
190
- - { reasoningEffort: high, description: "Deepest reasoning" }
 
191
  defaultReasoningEffort: medium
192
- inputModalities: [text]
193
- supportsPersonality: false
194
- upgrade: null
195
-
196
- - id: gpt-5.1-codex-high
197
- displayName: GPT-5.1 Codex High
198
- description: GPT-5.1 Codex — high reasoning tier
199
- isDefault: false
200
- supportedReasoningEfforts:
201
- - { reasoningEffort: high, description: "Deepest reasoning" }
202
- defaultReasoningEffort: high
203
- inputModalities: [text]
204
  supportsPersonality: false
205
  upgrade: null
206
 
207
- - id: gpt-5.1-codex-mid
208
- displayName: GPT-5.1 Codex Mid
209
- description: GPT-5.1 Codex — mid reasoning tier
210
  isDefault: false
211
  supportedReasoningEfforts:
212
- - { reasoningEffort: medium, description: "Balanced speed and quality" }
 
213
  defaultReasoningEffort: medium
214
  inputModalities: [text]
215
  supportsPersonality: false
216
  upgrade: null
217
 
218
- - id: gpt-5.1-codex-low
219
- displayName: GPT-5.1 Codex Low
220
- description: GPT-5.1 Codex — low reasoning tier (fastest)
221
- isDefault: false
222
- supportedReasoningEfforts:
223
- - { reasoningEffort: low, description: "Fastest responses" }
224
- defaultReasoningEffort: low
225
- inputModalities: [text]
226
- supportsPersonality: false
227
- upgrade: null
228
-
229
- - id: gpt-5.1-codex-max
230
- displayName: GPT-5.1 Codex Max
231
- description: GPT-5.1 Codex — extended context / deepest reasoning
232
  isDefault: false
233
  supportedReasoningEfforts:
234
  - { reasoningEffort: low, description: "Fastest responses" }
235
- - { reasoningEffort: medium, description: "Balanced speed and quality" }
236
  - { reasoningEffort: high, description: "Deepest reasoning" }
237
  defaultReasoningEffort: medium
238
  inputModalities: [text]
239
  supportsPersonality: false
240
  upgrade: null
241
 
242
- - id: gpt-5.1-codex-mini
243
- displayName: GPT-5.1 Codex Mini
244
- description: GPT-5.1 Codex Mini — lightweight, low-latency
245
- isDefault: false
246
- supportedReasoningEfforts:
247
- - { reasoningEffort: low, description: "Fastest responses" }
248
- - { reasoningEffort: medium, description: "Balanced speed and quality" }
249
- defaultReasoningEffort: low
250
- inputModalities: [text]
251
- supportsPersonality: false
252
- upgrade: null
253
-
254
- # ── Base GPT models (also usable via Codex endpoint) ───────────────
255
- - id: gpt-5.3
256
- displayName: GPT-5.3
257
- description: General-purpose GPT-5.3
258
  isDefault: false
259
  supportedReasoningEfforts:
260
  - { reasoningEffort: low, description: "Fastest responses" }
261
- - { reasoningEffort: medium, description: "Balanced speed and quality" }
262
  - { reasoningEffort: high, description: "Deepest reasoning" }
263
  defaultReasoningEffort: medium
264
- inputModalities: [text, image]
265
- supportsPersonality: true
266
- upgrade: null
267
-
268
- - id: gpt-5.2
269
- displayName: GPT-5.2
270
- description: General-purpose GPT-5.2
271
- isDefault: false
272
- supportedReasoningEfforts:
273
- - { reasoningEffort: low, description: "Fastest responses" }
274
- - { reasoningEffort: medium, description: "Balanced speed and quality" }
275
- - { reasoningEffort: high, description: "Deepest reasoning" }
276
- defaultReasoningEffort: medium
277
- inputModalities: [text, image]
278
- supportsPersonality: true
279
- upgrade: null
280
-
281
- - id: gpt-5.1
282
- displayName: GPT-5.1
283
- description: General-purpose GPT-5.1
284
- isDefault: false
285
- supportedReasoningEfforts:
286
- - { reasoningEffort: low, description: "Fastest responses" }
287
- - { reasoningEffort: medium, description: "Balanced speed and quality" }
288
- - { reasoningEffort: high, description: "Deepest reasoning" }
289
- defaultReasoningEffort: medium
290
- inputModalities: [text, image]
291
- supportsPersonality: true
292
  upgrade: null
293
 
294
  aliases:
295
- codex: "gpt-5.4"
 
2
  #
3
  # Sources:
4
  # 1. Static (below) — Codex-specific models (not returned by /backend-api/models)
5
+ # 2. Dynamic — general ChatGPT models fetched from /backend-api/codex/models
6
  #
7
  # Dynamic fetch merges with static; backend entries win for shared IDs.
8
+ # Models endpoint now requires ?client_version= query parameter.
9
+ #
10
+ # Last updated: 2026-03-10 (backend removed gpt-5.4, gpt-5.3-codex family)
11
 
12
  models:
13
+ # ── GPT-5.2 Codex (current flagship) ────────────────────────────────
14
+ - id: gpt-5.2-codex
15
+ displayName: GPT-5.2 Codex
16
+ description: Frontier agentic coding model
17
  isDefault: true
18
  supportedReasoningEfforts:
19
+ - { reasoningEffort: low, description: "Fast responses with lighter reasoning" }
20
+ - { reasoningEffort: medium, description: "Balances speed and reasoning depth" }
21
+ - { reasoningEffort: high, description: "Greater reasoning depth for complex problems" }
22
+ - { reasoningEffort: xhigh, description: "Extra high reasoning depth" }
 
23
  defaultReasoningEffort: medium
24
  inputModalities: [text, image]
25
  supportsPersonality: true
26
  upgrade: null
27
 
28
+ # ── GPT-5.2 (general-purpose) ────────────────────────────────────────
29
+ - id: gpt-5.2
30
+ displayName: GPT-5.2
31
+ description: Optimized for professional work and long-running agents
32
  isDefault: false
33
  supportedReasoningEfforts:
34
+ - { reasoningEffort: low, description: "Balances speed with some reasoning" }
35
+ - { reasoningEffort: medium, description: "Solid balance of reasoning depth and latency" }
36
+ - { reasoningEffort: high, description: "Maximizes reasoning depth" }
37
+ - { reasoningEffort: xhigh, description: "Extra high reasoning" }
38
  defaultReasoningEffort: medium
39
+ inputModalities: [text, image]
40
+ supportsPersonality: true
 
 
 
 
 
 
 
 
 
 
 
41
  upgrade: null
42
 
43
+ # ── GPT-5.1 Codex family ──────────────────────────────────────────
44
+ - id: gpt-5.1-codex-max
45
+ displayName: GPT-5.1 Codex Max
46
+ description: GPT-5.1 Codex — extended context / deepest reasoning
47
  isDefault: false
48
  supportedReasoningEfforts:
49
+ - { reasoningEffort: low, description: "Fast responses" }
50
  - { reasoningEffort: medium, description: "Balanced speed and quality" }
51
+ - { reasoningEffort: high, description: "Deepest reasoning" }
52
+ - { reasoningEffort: xhigh, description: "Extra high reasoning depth" }
53
  defaultReasoningEffort: medium
54
+ inputModalities: [text, image]
 
 
 
 
 
 
 
 
 
 
 
55
  supportsPersonality: false
56
  upgrade: null
57
 
58
+ - id: gpt-5.1-codex
59
+ displayName: GPT-5.1 Codex
60
+ description: GPT-5.1 Codex
61
  isDefault: false
62
  supportedReasoningEfforts:
63
  - { reasoningEffort: low, description: "Fastest responses" }
64
  - { reasoningEffort: medium, description: "Balanced speed and quality" }
65
  - { reasoningEffort: high, description: "Deepest reasoning" }
66
  defaultReasoningEffort: medium
67
+ inputModalities: [text, image]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  supportsPersonality: false
69
  upgrade: null
70
 
71
+ - id: gpt-5.1
72
+ displayName: GPT-5.1
73
+ description: General-purpose GPT-5.1
 
74
  isDefault: false
75
  supportedReasoningEfforts:
76
  - { reasoningEffort: low, description: "Fastest responses" }
77
  - { reasoningEffort: medium, description: "Balanced speed and quality" }
78
  - { reasoningEffort: high, description: "Deepest reasoning" }
79
  defaultReasoningEffort: medium
80
+ inputModalities: [text, image]
 
 
 
 
 
 
 
 
 
 
 
81
  supportsPersonality: false
82
  upgrade: null
83
 
84
+ - id: gpt-5.1-codex-mini
85
+ displayName: GPT-5.1 Codex Mini
86
+ description: GPT-5.1 Codex Mini lightweight, low-latency
87
  isDefault: false
88
  supportedReasoningEfforts:
89
+ - { reasoningEffort: medium, description: "Balanced" }
90
+ - { reasoningEffort: high, description: "Greater reasoning" }
91
  defaultReasoningEffort: medium
92
  inputModalities: [text]
93
  supportsPersonality: false
94
  upgrade: null
95
 
96
+ # ── GPT-5 Codex family ──────────────────────────────────────────────
97
+ - id: gpt-5-codex
98
+ displayName: GPT-5 Codex
99
+ description: GPT-5 Codex
 
 
 
 
 
 
 
 
 
 
100
  isDefault: false
101
  supportedReasoningEfforts:
102
  - { reasoningEffort: low, description: "Fastest responses" }
103
  - { reasoningEffort: medium, description: "Balanced speed and quality" }
104
  - { reasoningEffort: high, description: "Deepest reasoning" }
105
  defaultReasoningEffort: medium
106
+ inputModalities: [text, image]
 
 
 
 
 
 
 
 
 
 
 
 
107
  supportsPersonality: false
108
  upgrade: null
109
 
110
+ - id: gpt-5
111
+ displayName: GPT-5
112
+ description: General-purpose GPT-5
 
113
  isDefault: false
114
  supportedReasoningEfforts:
115
+ - { reasoningEffort: minimal, description: "Fastest responses with limited reasoning" }
116
+ - { reasoningEffort: low, description: "Fast responses" }
117
+ - { reasoningEffort: medium, description: "Balanced" }
118
+ - { reasoningEffort: high, description: "Deepest reasoning" }
119
  defaultReasoningEffort: medium
120
+ inputModalities: [text, image]
 
 
 
 
 
 
 
 
 
 
 
121
  supportsPersonality: false
122
  upgrade: null
123
 
124
+ - id: gpt-5-codex-mini
125
+ displayName: GPT-5 Codex Mini
126
+ description: GPT-5 Codex Mini lightweight
127
  isDefault: false
128
  supportedReasoningEfforts:
129
+ - { reasoningEffort: medium, description: "Balanced" }
130
+ - { reasoningEffort: high, description: "Greater reasoning" }
131
  defaultReasoningEffort: medium
132
  inputModalities: [text]
133
  supportsPersonality: false
134
  upgrade: null
135
 
136
+ # ── Open-source models ──────────────────────────────────────────────
137
+ - id: gpt-oss-120b
138
+ displayName: GPT-OSS 120B
139
+ description: Open-source 120B model
 
 
 
 
 
 
 
 
 
 
140
  isDefault: false
141
  supportedReasoningEfforts:
142
  - { reasoningEffort: low, description: "Fastest responses" }
143
+ - { reasoningEffort: medium, description: "Balanced" }
144
  - { reasoningEffort: high, description: "Deepest reasoning" }
145
  defaultReasoningEffort: medium
146
  inputModalities: [text]
147
  supportsPersonality: false
148
  upgrade: null
149
 
150
+ - id: gpt-oss-20b
151
+ displayName: GPT-OSS 20B
152
+ description: Open-source 20B model
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  isDefault: false
154
  supportedReasoningEfforts:
155
  - { reasoningEffort: low, description: "Fastest responses" }
156
+ - { reasoningEffort: medium, description: "Balanced" }
157
  - { reasoningEffort: high, description: "Deepest reasoning" }
158
  defaultReasoningEffort: medium
159
+ inputModalities: [text]
160
+ supportsPersonality: false
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  upgrade: null
162
 
163
  aliases:
164
+ codex: "gpt-5.2-codex"
src/models/model-store.ts CHANGED
@@ -69,14 +69,25 @@ export interface BackendModelEntry {
69
  description?: string;
70
  is_default?: boolean;
71
  default_reasoning_effort?: string;
 
72
  supported_reasoning_efforts?: Array<{
73
  reasoning_effort?: string;
74
  reasoningEffort?: string;
 
 
 
 
 
75
  description?: string;
76
  }>;
77
  input_modalities?: string[];
78
  supports_personality?: boolean;
79
  upgrade?: string | null;
 
 
 
 
 
80
  }
81
 
82
  /** Intermediate type with explicit efforts flag for merge logic. */
@@ -90,13 +101,21 @@ interface NormalizedModelWithMeta extends CodexModelInfo {
90
  function normalizeBackendModel(raw: BackendModelEntry): NormalizedModelWithMeta {
91
  const id = raw.slug ?? raw.id ?? raw.name ?? "unknown";
92
 
93
- const hasExplicitEfforts = Array.isArray(raw.supported_reasoning_efforts) && raw.supported_reasoning_efforts.length > 0;
94
-
95
- // Normalize reasoning efforts accept both snake_case and camelCase
96
- const efforts = (raw.supported_reasoning_efforts ?? []).map((e) => ({
97
- reasoningEffort: e.reasoningEffort ?? e.reasoning_effort ?? "medium",
98
- description: e.description ?? "",
99
- }));
 
 
 
 
 
 
 
 
100
 
101
  return {
102
  id,
@@ -106,7 +125,7 @@ function normalizeBackendModel(raw: BackendModelEntry): NormalizedModelWithMeta
106
  supportedReasoningEfforts: efforts.length > 0
107
  ? efforts
108
  : [{ reasoningEffort: "medium", description: "Default" }],
109
- defaultReasoningEffort: raw.default_reasoning_effort ?? "medium",
110
  inputModalities: raw.input_modalities ?? ["text"],
111
  supportsPersonality: raw.supports_personality ?? false,
112
  upgrade: raw.upgrade ?? null,
@@ -115,10 +134,11 @@ function normalizeBackendModel(raw: BackendModelEntry): NormalizedModelWithMeta
115
  };
116
  }
117
 
118
- /** Check if a model ID is Codex-compatible (gpt-X.Y-codex-* or bare gpt-X.Y). */
119
  function isCodexCompatibleId(id: string): boolean {
120
  if (/^gpt-\d+(\.\d+)?-codex/.test(id)) return true;
121
  if (/^gpt-\d+(\.\d+)?$/.test(id)) return true;
 
122
  return false;
123
  }
124
 
 
69
  description?: string;
70
  is_default?: boolean;
71
  default_reasoning_effort?: string;
72
+ default_reasoning_level?: string;
73
  supported_reasoning_efforts?: Array<{
74
  reasoning_effort?: string;
75
  reasoningEffort?: string;
76
+ effort?: string;
77
+ description?: string;
78
+ }>;
79
+ supported_reasoning_levels?: Array<{
80
+ effort?: string;
81
  description?: string;
82
  }>;
83
  input_modalities?: string[];
84
  supports_personality?: boolean;
85
  upgrade?: string | null;
86
+ prefer_websockets?: boolean;
87
+ context_window?: number;
88
+ available_in_plans?: string[];
89
+ priority?: number;
90
+ visibility?: string;
91
  }
92
 
93
  /** Intermediate type with explicit efforts flag for merge logic. */
 
101
  function normalizeBackendModel(raw: BackendModelEntry): NormalizedModelWithMeta {
102
  const id = raw.slug ?? raw.id ?? raw.name ?? "unknown";
103
 
104
+ // Accept both old (supported_reasoning_efforts) and new (supported_reasoning_levels) field names
105
+ const rawEfforts = raw.supported_reasoning_efforts ?? [];
106
+ const rawLevels = raw.supported_reasoning_levels ?? [];
107
+ const hasExplicitEfforts = rawEfforts.length > 0 || rawLevels.length > 0;
108
+
109
+ // Normalize reasoning efforts — accept effort, reasoning_effort, reasoningEffort keys
110
+ const efforts = rawEfforts.length > 0
111
+ ? rawEfforts.map((e) => ({
112
+ reasoningEffort: e.reasoningEffort ?? e.reasoning_effort ?? e.effort ?? "medium",
113
+ description: e.description ?? "",
114
+ }))
115
+ : rawLevels.map((e) => ({
116
+ reasoningEffort: e.effort ?? "medium",
117
+ description: e.description ?? "",
118
+ }));
119
 
120
  return {
121
  id,
 
125
  supportedReasoningEfforts: efforts.length > 0
126
  ? efforts
127
  : [{ reasoningEffort: "medium", description: "Default" }],
128
+ defaultReasoningEffort: raw.default_reasoning_effort ?? raw.default_reasoning_level ?? "medium",
129
  inputModalities: raw.input_modalities ?? ["text"],
130
  supportsPersonality: raw.supports_personality ?? false,
131
  upgrade: raw.upgrade ?? null,
 
134
  };
135
  }
136
 
137
+ /** Check if a model ID is Codex-compatible (gpt-X.Y-codex-*, bare gpt-X.Y, or gpt-oss-*). */
138
  function isCodexCompatibleId(id: string): boolean {
139
  if (/^gpt-\d+(\.\d+)?-codex/.test(id)) return true;
140
  if (/^gpt-\d+(\.\d+)?$/.test(id)) return true;
141
+ if (/^gpt-oss-/.test(id)) return true;
142
  return false;
143
  }
144
 
src/proxy/codex-api.ts CHANGED
@@ -146,8 +146,10 @@ export class CodexApi {
146
  const baseUrl = config.api.base_url;
147
 
148
  // Endpoints to probe (most specific first)
 
 
149
  const endpoints = [
150
- `${baseUrl}/codex/models`,
151
  `${baseUrl}/models`,
152
  `${baseUrl}/sentinel/chat-requirements`,
153
  ];
 
146
  const baseUrl = config.api.base_url;
147
 
148
  // Endpoints to probe (most specific first)
149
+ // /codex/models now requires ?client_version= query parameter
150
+ const clientVersion = config.client.app_version;
151
  const endpoints = [
152
+ `${baseUrl}/codex/models?client_version=${clientVersion}`,
153
  `${baseUrl}/models`,
154
  `${baseUrl}/sentinel/chat-requirements`,
155
  ];