@iam-brain/opencode-codex-auth 1.5.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/lib/codex-native/accounts.d.ts +1 -1
- package/dist/lib/codex-native/accounts.d.ts.map +1 -1
- package/dist/lib/codex-native/accounts.js +54 -17
- package/dist/lib/codex-native/accounts.js.map +1 -1
- package/dist/lib/codex-native/acquire-auth.d.ts.map +1 -1
- package/dist/lib/codex-native/acquire-auth.js +11 -5
- package/dist/lib/codex-native/acquire-auth.js.map +1 -1
- package/dist/lib/codex-native/auth-menu-flow.js +4 -4
- package/dist/lib/codex-native/auth-menu-flow.js.map +1 -1
- package/dist/lib/codex-native/chat-hooks.d.ts +8 -1
- package/dist/lib/codex-native/chat-hooks.d.ts.map +1 -1
- package/dist/lib/codex-native/chat-hooks.js +76 -25
- package/dist/lib/codex-native/chat-hooks.js.map +1 -1
- package/dist/lib/codex-native/client-identity.js +1 -1
- package/dist/lib/codex-native/oauth-auth-methods.d.ts.map +1 -1
- package/dist/lib/codex-native/oauth-auth-methods.js +27 -2
- package/dist/lib/codex-native/oauth-auth-methods.js.map +1 -1
- package/dist/lib/codex-native/oauth-persistence.d.ts.map +1 -1
- package/dist/lib/codex-native/oauth-persistence.js +2 -0
- package/dist/lib/codex-native/oauth-persistence.js.map +1 -1
- package/dist/lib/codex-native/oauth-utils.d.ts +1 -0
- package/dist/lib/codex-native/oauth-utils.d.ts.map +1 -1
- package/dist/lib/codex-native/oauth-utils.js +35 -15
- package/dist/lib/codex-native/oauth-utils.js.map +1 -1
- package/dist/lib/codex-native/openai-loader-fetch.d.ts +3 -1
- package/dist/lib/codex-native/openai-loader-fetch.d.ts.map +1 -1
- package/dist/lib/codex-native/openai-loader-fetch.js +50 -7
- package/dist/lib/codex-native/openai-loader-fetch.js.map +1 -1
- package/dist/lib/codex-native/reasoning-summary.d.ts +30 -0
- package/dist/lib/codex-native/reasoning-summary.d.ts.map +1 -0
- package/dist/lib/codex-native/reasoning-summary.js +98 -0
- package/dist/lib/codex-native/reasoning-summary.js.map +1 -0
- package/dist/lib/codex-native/request-routing.d.ts.map +1 -1
- package/dist/lib/codex-native/request-routing.js +12 -4
- package/dist/lib/codex-native/request-routing.js.map +1 -1
- package/dist/lib/codex-native/request-transform-model-service-tier.d.ts +2 -0
- package/dist/lib/codex-native/request-transform-model-service-tier.d.ts.map +1 -1
- package/dist/lib/codex-native/request-transform-model-service-tier.js +35 -1
- package/dist/lib/codex-native/request-transform-model-service-tier.js.map +1 -1
- package/dist/lib/codex-native/request-transform-model.d.ts +42 -10
- package/dist/lib/codex-native/request-transform-model.d.ts.map +1 -1
- package/dist/lib/codex-native/request-transform-model.js +262 -98
- package/dist/lib/codex-native/request-transform-model.js.map +1 -1
- package/dist/lib/codex-native/request-transform-payload.d.ts +9 -1
- package/dist/lib/codex-native/request-transform-payload.d.ts.map +1 -1
- package/dist/lib/codex-native/request-transform-payload.js +175 -47
- package/dist/lib/codex-native/request-transform-payload.js.map +1 -1
- package/dist/lib/codex-native/session-messages.d.ts.map +1 -1
- package/dist/lib/codex-native/session-messages.js +18 -1
- package/dist/lib/codex-native/session-messages.js.map +1 -1
- package/dist/lib/codex-native.d.ts +2 -1
- package/dist/lib/codex-native.d.ts.map +1 -1
- package/dist/lib/codex-native.js +91 -9
- package/dist/lib/codex-native.js.map +1 -1
- package/dist/lib/config/file.d.ts +3 -1
- package/dist/lib/config/file.d.ts.map +1 -1
- package/dist/lib/config/file.js +461 -52
- package/dist/lib/config/file.js.map +1 -1
- package/dist/lib/config/resolve.d.ts +6 -2
- package/dist/lib/config/resolve.d.ts.map +1 -1
- package/dist/lib/config/resolve.js +69 -11
- package/dist/lib/config/resolve.js.map +1 -1
- package/dist/lib/config/types.d.ts +22 -5
- package/dist/lib/config/types.d.ts.map +1 -1
- package/dist/lib/config/types.js +76 -31
- package/dist/lib/config/types.js.map +1 -1
- package/dist/lib/config.d.ts +3 -3
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +3 -3
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/fatal-errors.d.ts +5 -1
- package/dist/lib/fatal-errors.d.ts.map +1 -1
- package/dist/lib/fatal-errors.js +12 -2
- package/dist/lib/fatal-errors.js.map +1 -1
- package/dist/lib/fetch-orchestrator.d.ts.map +1 -1
- package/dist/lib/fetch-orchestrator.js +4 -1
- package/dist/lib/fetch-orchestrator.js.map +1 -1
- package/dist/lib/installer-cli.d.ts.map +1 -1
- package/dist/lib/installer-cli.js +38 -9
- package/dist/lib/installer-cli.js.map +1 -1
- package/dist/lib/model-catalog/provider.d.ts +4 -1
- package/dist/lib/model-catalog/provider.d.ts.map +1 -1
- package/dist/lib/model-catalog/provider.js +82 -9
- package/dist/lib/model-catalog/provider.js.map +1 -1
- package/dist/lib/model-catalog/shared.d.ts +27 -1
- package/dist/lib/model-catalog/shared.d.ts.map +1 -1
- package/dist/lib/model-catalog/shared.js +3 -2
- package/dist/lib/model-catalog/shared.js.map +1 -1
- package/dist/lib/model-catalog.d.ts +1 -1
- package/dist/lib/model-catalog.d.ts.map +1 -1
- package/dist/lib/model-catalog.js.map +1 -1
- package/dist/lib/persona-tool-cli.d.ts.map +1 -1
- package/dist/lib/persona-tool-cli.js +19 -7
- package/dist/lib/persona-tool-cli.js.map +1 -1
- package/dist/lib/personality-command.js +1 -1
- package/dist/lib/personality-create.d.ts.map +1 -1
- package/dist/lib/personality-create.js +28 -10
- package/dist/lib/personality-create.js.map +1 -1
- package/dist/lib/personality-skill.js +1 -1
- package/dist/lib/proactive-refresh.d.ts.map +1 -1
- package/dist/lib/proactive-refresh.js +11 -2
- package/dist/lib/proactive-refresh.js.map +1 -1
- package/dist/lib/storage/auth-state.d.ts.map +1 -1
- package/dist/lib/storage/auth-state.js +4 -3
- package/dist/lib/storage/auth-state.js.map +1 -1
- package/dist/lib/ui/auth-menu.d.ts +1 -0
- package/dist/lib/ui/auth-menu.d.ts.map +1 -1
- package/dist/lib/ui/auth-menu.js +1 -1
- package/dist/lib/ui/auth-menu.js.map +1 -1
- package/package.json +9 -6
- package/schemas/codex-config.schema.json +153 -11
package/dist/lib/config/file.js
CHANGED
|
@@ -3,7 +3,7 @@ import fsPromises from "node:fs/promises";
|
|
|
3
3
|
import os from "node:os";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { isRecord } from "../util.js";
|
|
6
|
-
import { CONFIG_FILE, DEFAULT_CODEX_CONFIG_TEMPLATE } from "./types.js";
|
|
6
|
+
import { CONFIG_FILE, DEFAULT_CODEX_CONFIG_TEMPLATE, LEGACY_CONFIG_FILE } from "./types.js";
|
|
7
7
|
function describeValueType(value) {
|
|
8
8
|
if (Array.isArray(value))
|
|
9
9
|
return "array";
|
|
@@ -11,8 +11,23 @@ function describeValueType(value) {
|
|
|
11
11
|
return "null";
|
|
12
12
|
return typeof value;
|
|
13
13
|
}
|
|
14
|
+
function describeValuePreview(value) {
|
|
15
|
+
if (typeof value === "string")
|
|
16
|
+
return JSON.stringify(value);
|
|
17
|
+
if (typeof value === "number" || typeof value === "boolean" || value === null || value === undefined) {
|
|
18
|
+
return String(value);
|
|
19
|
+
}
|
|
20
|
+
if (Array.isArray(value)) {
|
|
21
|
+
return `array(${value.length})`;
|
|
22
|
+
}
|
|
23
|
+
if (typeof value === "object") {
|
|
24
|
+
const keys = Object.keys(value);
|
|
25
|
+
return keys.length > 0 ? `object(${keys.slice(0, 3).join(", ")})` : "object";
|
|
26
|
+
}
|
|
27
|
+
return String(value);
|
|
28
|
+
}
|
|
14
29
|
function pushValidationIssue(issues, input) {
|
|
15
|
-
issues.push(`${input.path}: expected ${input.expected},
|
|
30
|
+
issues.push(`${input.path}: expected ${input.expected}, found ${describeValueType(input.actual)} (${describeValuePreview(input.actual)})`);
|
|
16
31
|
}
|
|
17
32
|
export function parseEnvBoolean(value) {
|
|
18
33
|
if (value === undefined)
|
|
@@ -91,6 +106,85 @@ function stripJsonComments(raw) {
|
|
|
91
106
|
}
|
|
92
107
|
return out;
|
|
93
108
|
}
|
|
109
|
+
const SUPPORTED_INCLUDE_OPTIONS = [
|
|
110
|
+
"reasoning.encrypted_content",
|
|
111
|
+
"file_search_call.results",
|
|
112
|
+
"message.output_text.logprobs"
|
|
113
|
+
];
|
|
114
|
+
function normalizeNonEmptyString(value) {
|
|
115
|
+
if (typeof value !== "string")
|
|
116
|
+
return undefined;
|
|
117
|
+
const trimmed = value.trim();
|
|
118
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
119
|
+
}
|
|
120
|
+
function deriveReasoningSummaryAlias(value) {
|
|
121
|
+
if (value === undefined)
|
|
122
|
+
return undefined;
|
|
123
|
+
return value !== "none";
|
|
124
|
+
}
|
|
125
|
+
function deriveVerbosityEnabledAlias(value) {
|
|
126
|
+
if (value === undefined)
|
|
127
|
+
return undefined;
|
|
128
|
+
return value !== "none";
|
|
129
|
+
}
|
|
130
|
+
function deriveVerbosityAlias(value) {
|
|
131
|
+
if (value === undefined || value === "none")
|
|
132
|
+
return undefined;
|
|
133
|
+
return value;
|
|
134
|
+
}
|
|
135
|
+
function normalizeReasoningSummaryOption(value) {
|
|
136
|
+
if (typeof value !== "string")
|
|
137
|
+
return undefined;
|
|
138
|
+
const normalized = value.trim().toLowerCase();
|
|
139
|
+
if (normalized === "auto" || normalized === "concise" || normalized === "detailed" || normalized === "none") {
|
|
140
|
+
return normalized;
|
|
141
|
+
}
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
export function normalizeTextVerbosityOption(value) {
|
|
145
|
+
if (typeof value !== "string")
|
|
146
|
+
return undefined;
|
|
147
|
+
const normalized = value.trim().toLowerCase();
|
|
148
|
+
if (normalized === "default" ||
|
|
149
|
+
normalized === "low" ||
|
|
150
|
+
normalized === "medium" ||
|
|
151
|
+
normalized === "high" ||
|
|
152
|
+
normalized === "none") {
|
|
153
|
+
return normalized;
|
|
154
|
+
}
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
function normalizeIncludeOptions(value) {
|
|
158
|
+
if (!Array.isArray(value))
|
|
159
|
+
return undefined;
|
|
160
|
+
const out = [];
|
|
161
|
+
const seen = new Set();
|
|
162
|
+
for (const entry of value) {
|
|
163
|
+
if (typeof entry !== "string")
|
|
164
|
+
continue;
|
|
165
|
+
const normalized = entry.trim().toLowerCase();
|
|
166
|
+
if (!SUPPORTED_INCLUDE_OPTIONS.includes(normalized))
|
|
167
|
+
continue;
|
|
168
|
+
if (seen.has(normalized))
|
|
169
|
+
continue;
|
|
170
|
+
seen.add(normalized);
|
|
171
|
+
out.push(normalized);
|
|
172
|
+
}
|
|
173
|
+
return out.length > 0 ? out : undefined;
|
|
174
|
+
}
|
|
175
|
+
function normalizeServiceTierInput(value) {
|
|
176
|
+
if (typeof value !== "string") {
|
|
177
|
+
return { value: undefined, usedDeprecatedDefaultAlias: false };
|
|
178
|
+
}
|
|
179
|
+
const normalized = value.trim().toLowerCase();
|
|
180
|
+
if (normalized === "default") {
|
|
181
|
+
return { value: "auto", usedDeprecatedDefaultAlias: true };
|
|
182
|
+
}
|
|
183
|
+
if (normalized === "auto" || normalized === "priority" || normalized === "flex") {
|
|
184
|
+
return { value: normalized, usedDeprecatedDefaultAlias: false };
|
|
185
|
+
}
|
|
186
|
+
return { value: undefined, usedDeprecatedDefaultAlias: false };
|
|
187
|
+
}
|
|
94
188
|
function normalizeModelBehaviorSettings(raw) {
|
|
95
189
|
if (!isRecord(raw))
|
|
96
190
|
return undefined;
|
|
@@ -98,21 +192,58 @@ function normalizeModelBehaviorSettings(raw) {
|
|
|
98
192
|
const personality = normalizePersonalityOption(raw.personality);
|
|
99
193
|
if (personality)
|
|
100
194
|
out.personality = personality;
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
195
|
+
const reasoningEffort = normalizeNonEmptyString(raw.reasoningEffort);
|
|
196
|
+
if (reasoningEffort)
|
|
197
|
+
out.reasoningEffort = reasoningEffort;
|
|
198
|
+
const reasoningSummary = normalizeReasoningSummaryOption(raw.reasoningSummary);
|
|
199
|
+
if (reasoningSummary) {
|
|
200
|
+
out.reasoningSummary = reasoningSummary;
|
|
201
|
+
}
|
|
202
|
+
else if (typeof raw.reasoningSummaries === "boolean") {
|
|
203
|
+
out.reasoningSummary = raw.reasoningSummaries ? "auto" : "none";
|
|
204
|
+
}
|
|
205
|
+
else if (typeof raw.thinkingSummaries === "boolean") {
|
|
206
|
+
out.reasoningSummary = raw.thinkingSummaries ? "auto" : "none";
|
|
207
|
+
}
|
|
208
|
+
out.reasoningSummaries = deriveReasoningSummaryAlias(out.reasoningSummary);
|
|
209
|
+
const textVerbosity = normalizeTextVerbosityOption(raw.textVerbosity);
|
|
210
|
+
if (textVerbosity) {
|
|
211
|
+
out.textVerbosity = textVerbosity;
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
const verbosityEnabled = typeof raw.verbosityEnabled === "boolean" ? raw.verbosityEnabled : undefined;
|
|
215
|
+
const verbosity = normalizeVerbosityOption(raw.verbosity);
|
|
216
|
+
if (verbosityEnabled === false) {
|
|
217
|
+
out.textVerbosity = "none";
|
|
218
|
+
}
|
|
219
|
+
else if (verbosity) {
|
|
220
|
+
out.textVerbosity = verbosity;
|
|
221
|
+
}
|
|
222
|
+
else if (verbosityEnabled === true) {
|
|
223
|
+
out.textVerbosity = "default";
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
out.verbosityEnabled = deriveVerbosityEnabledAlias(out.textVerbosity);
|
|
227
|
+
out.verbosity = deriveVerbosityAlias(out.textVerbosity);
|
|
228
|
+
const serviceTier = normalizeServiceTierInput(raw.serviceTier);
|
|
229
|
+
if (serviceTier.value)
|
|
230
|
+
out.serviceTier = serviceTier.value;
|
|
231
|
+
const include = normalizeIncludeOptions(raw.include);
|
|
232
|
+
if (include)
|
|
233
|
+
out.include = include;
|
|
234
|
+
if (typeof raw.parallelToolCalls === "boolean") {
|
|
235
|
+
out.parallelToolCalls = raw.parallelToolCalls;
|
|
236
|
+
}
|
|
111
237
|
if (!out.personality &&
|
|
112
|
-
out.
|
|
238
|
+
!out.reasoningEffort &&
|
|
239
|
+
out.reasoningSummary === undefined &&
|
|
240
|
+
out.reasoningSummaries === undefined &&
|
|
241
|
+
out.textVerbosity === undefined &&
|
|
113
242
|
out.verbosityEnabled === undefined &&
|
|
114
243
|
out.verbosity === undefined &&
|
|
115
|
-
out.serviceTier === undefined
|
|
244
|
+
out.serviceTier === undefined &&
|
|
245
|
+
out.include === undefined &&
|
|
246
|
+
out.parallelToolCalls === undefined) {
|
|
116
247
|
return undefined;
|
|
117
248
|
}
|
|
118
249
|
return out;
|
|
@@ -131,10 +262,15 @@ function normalizeModelConfigOverride(raw) {
|
|
|
131
262
|
continue;
|
|
132
263
|
variantMap[variantName] = {
|
|
133
264
|
...(normalized.personality ? { personality: normalized.personality } : {}),
|
|
134
|
-
...(normalized.
|
|
265
|
+
...(normalized.reasoningEffort ? { reasoningEffort: normalized.reasoningEffort } : {}),
|
|
266
|
+
...(normalized.reasoningSummary ? { reasoningSummary: normalized.reasoningSummary } : {}),
|
|
267
|
+
...(normalized.reasoningSummaries !== undefined ? { reasoningSummaries: normalized.reasoningSummaries } : {}),
|
|
268
|
+
...(normalized.textVerbosity ? { textVerbosity: normalized.textVerbosity } : {}),
|
|
135
269
|
...(normalized.verbosityEnabled !== undefined ? { verbosityEnabled: normalized.verbosityEnabled } : {}),
|
|
136
270
|
...(normalized.verbosity ? { verbosity: normalized.verbosity } : {}),
|
|
137
|
-
...(normalized.serviceTier ? { serviceTier: normalized.serviceTier } : {})
|
|
271
|
+
...(normalized.serviceTier ? { serviceTier: normalized.serviceTier } : {}),
|
|
272
|
+
...(normalized.include ? { include: normalized.include } : {}),
|
|
273
|
+
...(normalized.parallelToolCalls !== undefined ? { parallelToolCalls: normalized.parallelToolCalls } : {})
|
|
138
274
|
};
|
|
139
275
|
}
|
|
140
276
|
if (Object.keys(variantMap).length > 0) {
|
|
@@ -146,13 +282,36 @@ function normalizeModelConfigOverride(raw) {
|
|
|
146
282
|
}
|
|
147
283
|
return {
|
|
148
284
|
...(modelBehavior?.personality ? { personality: modelBehavior.personality } : {}),
|
|
149
|
-
...(modelBehavior?.
|
|
285
|
+
...(modelBehavior?.reasoningEffort ? { reasoningEffort: modelBehavior.reasoningEffort } : {}),
|
|
286
|
+
...(modelBehavior?.reasoningSummary ? { reasoningSummary: modelBehavior.reasoningSummary } : {}),
|
|
287
|
+
...(modelBehavior?.reasoningSummaries !== undefined
|
|
288
|
+
? { reasoningSummaries: modelBehavior.reasoningSummaries }
|
|
289
|
+
: {}),
|
|
290
|
+
...(modelBehavior?.textVerbosity ? { textVerbosity: modelBehavior.textVerbosity } : {}),
|
|
150
291
|
...(modelBehavior?.verbosityEnabled !== undefined ? { verbosityEnabled: modelBehavior.verbosityEnabled } : {}),
|
|
151
292
|
...(modelBehavior?.verbosity ? { verbosity: modelBehavior.verbosity } : {}),
|
|
152
293
|
...(modelBehavior?.serviceTier ? { serviceTier: modelBehavior.serviceTier } : {}),
|
|
294
|
+
...(modelBehavior?.include ? { include: modelBehavior.include } : {}),
|
|
295
|
+
...(modelBehavior?.parallelToolCalls !== undefined ? { parallelToolCalls: modelBehavior.parallelToolCalls } : {}),
|
|
153
296
|
...(variants ? { variants } : {})
|
|
154
297
|
};
|
|
155
298
|
}
|
|
299
|
+
function normalizeCustomModelConfig(raw) {
|
|
300
|
+
if (!isRecord(raw))
|
|
301
|
+
return undefined;
|
|
302
|
+
const behavior = normalizeModelConfigOverride(raw);
|
|
303
|
+
const targetModel = normalizeNonEmptyString(raw.targetModel);
|
|
304
|
+
const name = normalizeNonEmptyString(raw.name);
|
|
305
|
+
if (!targetModel && !behavior && !name)
|
|
306
|
+
return undefined;
|
|
307
|
+
if (!targetModel)
|
|
308
|
+
return undefined;
|
|
309
|
+
return {
|
|
310
|
+
targetModel,
|
|
311
|
+
...(name ? { name } : {}),
|
|
312
|
+
...(behavior ?? {})
|
|
313
|
+
};
|
|
314
|
+
}
|
|
156
315
|
function normalizeNewBehaviorSections(raw) {
|
|
157
316
|
const global = normalizeModelBehaviorSettings(raw.global);
|
|
158
317
|
const perModelRaw = isRecord(raw.perModel) ? raw.perModel : undefined;
|
|
@@ -176,6 +335,22 @@ function normalizeNewBehaviorSections(raw) {
|
|
|
176
335
|
...(perModel ? { perModel } : {})
|
|
177
336
|
};
|
|
178
337
|
}
|
|
338
|
+
function normalizeCustomModels(raw) {
|
|
339
|
+
const customModelsRaw = isRecord(raw.customModels) ? raw.customModels : undefined;
|
|
340
|
+
if (!customModelsRaw)
|
|
341
|
+
return undefined;
|
|
342
|
+
const out = {};
|
|
343
|
+
for (const [slug, value] of Object.entries(customModelsRaw)) {
|
|
344
|
+
const normalizedSlug = normalizeNonEmptyString(slug)?.toLowerCase();
|
|
345
|
+
if (!normalizedSlug)
|
|
346
|
+
continue;
|
|
347
|
+
const normalized = normalizeCustomModelConfig(value);
|
|
348
|
+
if (!normalized)
|
|
349
|
+
continue;
|
|
350
|
+
out[normalizedSlug] = normalized;
|
|
351
|
+
}
|
|
352
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
353
|
+
}
|
|
179
354
|
function validateModelBehaviorShape(value, pathPrefix, issues) {
|
|
180
355
|
if (!isRecord(value)) {
|
|
181
356
|
pushValidationIssue(issues, { path: pathPrefix, expected: "object", actual: value });
|
|
@@ -184,6 +359,31 @@ function validateModelBehaviorShape(value, pathPrefix, issues) {
|
|
|
184
359
|
if ("personality" in value && typeof value.personality !== "string") {
|
|
185
360
|
pushValidationIssue(issues, { path: `${pathPrefix}.personality`, expected: "string", actual: value.personality });
|
|
186
361
|
}
|
|
362
|
+
if ("reasoningEffort" in value && typeof value.reasoningEffort !== "string") {
|
|
363
|
+
pushValidationIssue(issues, {
|
|
364
|
+
path: `${pathPrefix}.reasoningEffort`,
|
|
365
|
+
expected: "string",
|
|
366
|
+
actual: value.reasoningEffort
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
if ("reasoningSummary" in value) {
|
|
370
|
+
const reasoningSummary = value.reasoningSummary;
|
|
371
|
+
const normalized = typeof reasoningSummary === "string" ? reasoningSummary.trim().toLowerCase() : "";
|
|
372
|
+
if (!(normalized === "auto" || normalized === "concise" || normalized === "detailed" || normalized === "none")) {
|
|
373
|
+
pushValidationIssue(issues, {
|
|
374
|
+
path: `${pathPrefix}.reasoningSummary`,
|
|
375
|
+
expected: '"auto" | "concise" | "detailed" | "none"',
|
|
376
|
+
actual: reasoningSummary
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
if ("reasoningSummaries" in value && typeof value.reasoningSummaries !== "boolean") {
|
|
381
|
+
pushValidationIssue(issues, {
|
|
382
|
+
path: `${pathPrefix}.reasoningSummaries`,
|
|
383
|
+
expected: "boolean",
|
|
384
|
+
actual: value.reasoningSummaries
|
|
385
|
+
});
|
|
386
|
+
}
|
|
187
387
|
if ("thinkingSummaries" in value && typeof value.thinkingSummaries !== "boolean") {
|
|
188
388
|
pushValidationIssue(issues, {
|
|
189
389
|
path: `${pathPrefix}.thinkingSummaries`,
|
|
@@ -209,17 +409,82 @@ function validateModelBehaviorShape(value, pathPrefix, issues) {
|
|
|
209
409
|
});
|
|
210
410
|
}
|
|
211
411
|
}
|
|
412
|
+
if ("textVerbosity" in value) {
|
|
413
|
+
const textVerbosity = value.textVerbosity;
|
|
414
|
+
const normalized = typeof textVerbosity === "string" ? textVerbosity.trim().toLowerCase() : "";
|
|
415
|
+
if (!(normalized === "default" ||
|
|
416
|
+
normalized === "low" ||
|
|
417
|
+
normalized === "medium" ||
|
|
418
|
+
normalized === "high" ||
|
|
419
|
+
normalized === "none")) {
|
|
420
|
+
pushValidationIssue(issues, {
|
|
421
|
+
path: `${pathPrefix}.textVerbosity`,
|
|
422
|
+
expected: '"default" | "low" | "medium" | "high" | "none"',
|
|
423
|
+
actual: textVerbosity
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
}
|
|
212
427
|
if ("serviceTier" in value) {
|
|
213
428
|
const serviceTier = value.serviceTier;
|
|
214
429
|
const normalized = typeof serviceTier === "string" ? serviceTier.trim().toLowerCase() : "";
|
|
215
|
-
if (!(normalized === "default" || normalized === "priority" || normalized === "flex")) {
|
|
430
|
+
if (!(normalized === "default" || normalized === "auto" || normalized === "priority" || normalized === "flex")) {
|
|
216
431
|
pushValidationIssue(issues, {
|
|
217
432
|
path: `${pathPrefix}.serviceTier`,
|
|
218
|
-
expected: '"
|
|
433
|
+
expected: '"auto" | "priority" | "flex" (deprecated alias: "default")',
|
|
219
434
|
actual: serviceTier
|
|
220
435
|
});
|
|
221
436
|
}
|
|
222
437
|
}
|
|
438
|
+
if ("include" in value) {
|
|
439
|
+
if (!Array.isArray(value.include)) {
|
|
440
|
+
pushValidationIssue(issues, {
|
|
441
|
+
path: `${pathPrefix}.include`,
|
|
442
|
+
expected: "array",
|
|
443
|
+
actual: value.include
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
for (const entry of value.include) {
|
|
448
|
+
const normalized = typeof entry === "string" ? entry.trim().toLowerCase() : "";
|
|
449
|
+
if (!SUPPORTED_INCLUDE_OPTIONS.includes(normalized)) {
|
|
450
|
+
pushValidationIssue(issues, {
|
|
451
|
+
path: `${pathPrefix}.include`,
|
|
452
|
+
expected: SUPPORTED_INCLUDE_OPTIONS.map((item) => `"${item}"`).join(" | "),
|
|
453
|
+
actual: entry
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
if ("parallelToolCalls" in value && typeof value.parallelToolCalls !== "boolean") {
|
|
460
|
+
pushValidationIssue(issues, {
|
|
461
|
+
path: `${pathPrefix}.parallelToolCalls`,
|
|
462
|
+
expected: "boolean",
|
|
463
|
+
actual: value.parallelToolCalls
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
function validateCustomModelShape(value, pathPrefix, issues) {
|
|
468
|
+
validateModelBehaviorShape(value, pathPrefix, issues);
|
|
469
|
+
if (!isRecord(value))
|
|
470
|
+
return;
|
|
471
|
+
if ("targetModel" in value && typeof value.targetModel !== "string") {
|
|
472
|
+
pushValidationIssue(issues, {
|
|
473
|
+
path: `${pathPrefix}.targetModel`,
|
|
474
|
+
expected: "string",
|
|
475
|
+
actual: value.targetModel
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
if (!("targetModel" in value)) {
|
|
479
|
+
issues.push(`${pathPrefix}.targetModel: expected string, found missing (custom models require targetModel)`);
|
|
480
|
+
}
|
|
481
|
+
if ("name" in value && typeof value.name !== "string") {
|
|
482
|
+
pushValidationIssue(issues, {
|
|
483
|
+
path: `${pathPrefix}.name`,
|
|
484
|
+
expected: "string",
|
|
485
|
+
actual: value.name
|
|
486
|
+
});
|
|
487
|
+
}
|
|
223
488
|
}
|
|
224
489
|
export function parseConfigJsonWithComments(raw) {
|
|
225
490
|
return JSON.parse(stripJsonComments(raw));
|
|
@@ -282,13 +547,7 @@ export function normalizeVerbosityOption(value) {
|
|
|
282
547
|
return undefined;
|
|
283
548
|
}
|
|
284
549
|
export function normalizeServiceTierOption(value) {
|
|
285
|
-
|
|
286
|
-
return undefined;
|
|
287
|
-
const normalized = value.trim().toLowerCase();
|
|
288
|
-
if (normalized === "default" || normalized === "priority" || normalized === "flex") {
|
|
289
|
-
return normalized;
|
|
290
|
-
}
|
|
291
|
-
return undefined;
|
|
550
|
+
return normalizeServiceTierInput(value).value;
|
|
292
551
|
}
|
|
293
552
|
export function validateConfigFileObject(raw) {
|
|
294
553
|
const issues = [];
|
|
@@ -400,12 +659,96 @@ export function validateConfigFileObject(raw) {
|
|
|
400
659
|
}
|
|
401
660
|
}
|
|
402
661
|
}
|
|
662
|
+
if ("customModels" in raw) {
|
|
663
|
+
if (!isRecord(raw.customModels)) {
|
|
664
|
+
pushValidationIssue(issues, { path: "customModels", expected: "object", actual: raw.customModels });
|
|
665
|
+
}
|
|
666
|
+
else {
|
|
667
|
+
for (const [slug, value] of Object.entries(raw.customModels)) {
|
|
668
|
+
validateCustomModelShape(value, `customModels.${slug}`, issues);
|
|
669
|
+
if (!isRecord(value) || !("variants" in value))
|
|
670
|
+
continue;
|
|
671
|
+
const variants = value.variants;
|
|
672
|
+
if (!isRecord(variants)) {
|
|
673
|
+
pushValidationIssue(issues, {
|
|
674
|
+
path: `customModels.${slug}.variants`,
|
|
675
|
+
expected: "object",
|
|
676
|
+
actual: variants
|
|
677
|
+
});
|
|
678
|
+
continue;
|
|
679
|
+
}
|
|
680
|
+
for (const [variantName, variantValue] of Object.entries(variants)) {
|
|
681
|
+
validateModelBehaviorShape(variantValue, `customModels.${slug}.variants.${variantName}`, issues);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
403
686
|
return { valid: issues.length === 0, issues };
|
|
404
687
|
}
|
|
405
688
|
export function parseConfigFileObject(raw) {
|
|
689
|
+
return parseConfigFileObjectWithMetadata(raw).config;
|
|
690
|
+
}
|
|
691
|
+
function collectDeprecatedModelBehaviorKeys(raw) {
|
|
406
692
|
if (!isRecord(raw))
|
|
407
|
-
return
|
|
693
|
+
return [];
|
|
694
|
+
const keys = [];
|
|
695
|
+
const collectBehaviorAlias = (value, pathPrefix) => {
|
|
696
|
+
if (!isRecord(value))
|
|
697
|
+
return;
|
|
698
|
+
if (typeof value.reasoningSummaries === "boolean") {
|
|
699
|
+
keys.push(`${pathPrefix}.reasoningSummaries`);
|
|
700
|
+
}
|
|
701
|
+
if (typeof value.thinkingSummaries === "boolean") {
|
|
702
|
+
keys.push(`${pathPrefix}.thinkingSummaries`);
|
|
703
|
+
}
|
|
704
|
+
if ("verbosityEnabled" in value) {
|
|
705
|
+
keys.push(`${pathPrefix}.verbosityEnabled`);
|
|
706
|
+
}
|
|
707
|
+
if ("verbosity" in value) {
|
|
708
|
+
keys.push(`${pathPrefix}.verbosity`);
|
|
709
|
+
}
|
|
710
|
+
if (typeof value.serviceTier === "string" && value.serviceTier.trim().toLowerCase() === "default") {
|
|
711
|
+
keys.push(`${pathPrefix}.serviceTier="default"`);
|
|
712
|
+
}
|
|
713
|
+
};
|
|
714
|
+
collectBehaviorAlias(raw.global, "global");
|
|
715
|
+
if (isRecord(raw.perModel)) {
|
|
716
|
+
for (const [modelName, modelValue] of Object.entries(raw.perModel)) {
|
|
717
|
+
collectBehaviorAlias(modelValue, `perModel.${modelName}`);
|
|
718
|
+
if (!isRecord(modelValue))
|
|
719
|
+
continue;
|
|
720
|
+
const variants = isRecord(modelValue.variants) ? modelValue.variants : undefined;
|
|
721
|
+
if (!variants)
|
|
722
|
+
continue;
|
|
723
|
+
for (const [variantName, variantValue] of Object.entries(variants)) {
|
|
724
|
+
collectBehaviorAlias(variantValue, `perModel.${modelName}.variants.${variantName}`);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
if (isRecord(raw.customModels)) {
|
|
729
|
+
for (const [slug, modelValue] of Object.entries(raw.customModels)) {
|
|
730
|
+
collectBehaviorAlias(modelValue, `customModels.${slug}`);
|
|
731
|
+
if (!isRecord(modelValue))
|
|
732
|
+
continue;
|
|
733
|
+
const variants = isRecord(modelValue.variants) ? modelValue.variants : undefined;
|
|
734
|
+
if (!variants)
|
|
735
|
+
continue;
|
|
736
|
+
for (const [variantName, variantValue] of Object.entries(variants)) {
|
|
737
|
+
collectBehaviorAlias(variantValue, `customModels.${slug}.variants.${variantName}`);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
return keys;
|
|
742
|
+
}
|
|
743
|
+
function parseConfigFileObjectWithMetadata(raw) {
|
|
744
|
+
if (!isRecord(raw)) {
|
|
745
|
+
return {
|
|
746
|
+
config: {},
|
|
747
|
+
deprecatedKeys: []
|
|
748
|
+
};
|
|
749
|
+
}
|
|
408
750
|
const behaviorSettings = normalizeNewBehaviorSections(raw);
|
|
751
|
+
const customModels = normalizeCustomModels(raw);
|
|
409
752
|
const personalityFromBehavior = behaviorSettings?.global?.personality;
|
|
410
753
|
const runtime = isRecord(raw.runtime) ? raw.runtime : undefined;
|
|
411
754
|
const debug = typeof raw.debug === "boolean" ? raw.debug : undefined;
|
|
@@ -426,28 +769,32 @@ export function parseConfigFileObject(raw) {
|
|
|
426
769
|
const collaborationProfileEnabled = typeof runtime?.collaborationProfile === "boolean" ? runtime.collaborationProfile : undefined;
|
|
427
770
|
const orchestratorSubagentsEnabled = typeof runtime?.orchestratorSubagents === "boolean" ? runtime.orchestratorSubagents : undefined;
|
|
428
771
|
return {
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
772
|
+
config: {
|
|
773
|
+
debug,
|
|
774
|
+
proactiveRefresh,
|
|
775
|
+
proactiveRefreshBufferMs,
|
|
776
|
+
quiet: quietMode,
|
|
777
|
+
quietMode,
|
|
778
|
+
pidOffsetEnabled,
|
|
779
|
+
personality: personalityFromBehavior,
|
|
780
|
+
mode,
|
|
781
|
+
rotationStrategy,
|
|
782
|
+
promptCacheKeyStrategy,
|
|
783
|
+
spoofMode,
|
|
784
|
+
compatInputSanitizer,
|
|
785
|
+
remapDeveloperMessagesToUser,
|
|
786
|
+
codexCompactionOverride,
|
|
787
|
+
headerSnapshots,
|
|
788
|
+
headerSnapshotBodies,
|
|
789
|
+
headerTransformDebug,
|
|
790
|
+
collaborationProfile: collaborationProfileEnabled,
|
|
791
|
+
collaborationProfileEnabled,
|
|
792
|
+
orchestratorSubagents: orchestratorSubagentsEnabled,
|
|
793
|
+
orchestratorSubagentsEnabled,
|
|
794
|
+
behaviorSettings,
|
|
795
|
+
customModels
|
|
796
|
+
},
|
|
797
|
+
deprecatedKeys: collectDeprecatedModelBehaviorKeys(raw)
|
|
451
798
|
};
|
|
452
799
|
}
|
|
453
800
|
export function resolveDefaultConfigPath(env) {
|
|
@@ -457,9 +804,51 @@ export function resolveDefaultConfigPath(env) {
|
|
|
457
804
|
}
|
|
458
805
|
return path.join(os.homedir(), ".config", "opencode", CONFIG_FILE);
|
|
459
806
|
}
|
|
807
|
+
export function resolveLegacyDefaultConfigPath(env) {
|
|
808
|
+
const xdgRoot = env.XDG_CONFIG_HOME?.trim();
|
|
809
|
+
if (xdgRoot) {
|
|
810
|
+
return path.join(xdgRoot, "opencode", LEGACY_CONFIG_FILE);
|
|
811
|
+
}
|
|
812
|
+
return path.join(os.homedir(), ".config", "opencode", LEGACY_CONFIG_FILE);
|
|
813
|
+
}
|
|
814
|
+
function quarantineLegacyConfigSync(filePath) {
|
|
815
|
+
try {
|
|
816
|
+
const quarantineDir = path.join(path.dirname(filePath), "quarantine");
|
|
817
|
+
fs.mkdirSync(quarantineDir, { recursive: true });
|
|
818
|
+
const dest = path.join(quarantineDir, `${path.basename(filePath)}.${Date.now()}.quarantine.json`);
|
|
819
|
+
fs.renameSync(filePath, dest);
|
|
820
|
+
return dest;
|
|
821
|
+
}
|
|
822
|
+
catch {
|
|
823
|
+
return undefined;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
function resolveDefaultConfigCandidates(env) {
|
|
827
|
+
const filePath = resolveDefaultConfigPath(env);
|
|
828
|
+
const legacyPath = resolveLegacyDefaultConfigPath(env);
|
|
829
|
+
const hasFile = fs.existsSync(filePath);
|
|
830
|
+
const hasLegacy = fs.existsSync(legacyPath);
|
|
831
|
+
if (hasFile && hasLegacy) {
|
|
832
|
+
return [filePath, legacyPath];
|
|
833
|
+
}
|
|
834
|
+
if (hasFile)
|
|
835
|
+
return [filePath];
|
|
836
|
+
if (hasLegacy)
|
|
837
|
+
return [legacyPath];
|
|
838
|
+
return [filePath];
|
|
839
|
+
}
|
|
460
840
|
export async function ensureDefaultConfigFile(input = {}) {
|
|
461
841
|
const env = input.env ?? process.env;
|
|
462
|
-
const filePath = input.filePath ??
|
|
842
|
+
const filePath = input.filePath ??
|
|
843
|
+
(() => {
|
|
844
|
+
const canonicalPath = resolveDefaultConfigPath(env);
|
|
845
|
+
const legacyPath = resolveLegacyDefaultConfigPath(env);
|
|
846
|
+
if (fs.existsSync(canonicalPath))
|
|
847
|
+
return canonicalPath;
|
|
848
|
+
if (fs.existsSync(legacyPath))
|
|
849
|
+
return legacyPath;
|
|
850
|
+
return canonicalPath;
|
|
851
|
+
})();
|
|
463
852
|
const overwrite = input.overwrite === true;
|
|
464
853
|
if (!overwrite && fs.existsSync(filePath)) {
|
|
465
854
|
return { filePath, created: false };
|
|
@@ -479,7 +868,15 @@ export async function ensureDefaultConfigFile(input = {}) {
|
|
|
479
868
|
export function loadConfigFile(input = {}) {
|
|
480
869
|
const env = input.env ?? process.env;
|
|
481
870
|
const explicitPath = input.filePath ?? env.OPENCODE_OPENAI_MULTI_CONFIG_PATH?.trim();
|
|
482
|
-
const candidates = explicitPath ? [explicitPath] :
|
|
871
|
+
const candidates = explicitPath ? [explicitPath] : resolveDefaultConfigCandidates(env);
|
|
872
|
+
const canonicalPath = explicitPath ? undefined : resolveDefaultConfigPath(env);
|
|
873
|
+
const legacyPath = explicitPath ? undefined : resolveLegacyDefaultConfigPath(env);
|
|
874
|
+
const shouldQuarantineLegacyAfterCanonicalLoad = !explicitPath &&
|
|
875
|
+
canonicalPath !== undefined &&
|
|
876
|
+
legacyPath !== undefined &&
|
|
877
|
+
candidates.length > 1 &&
|
|
878
|
+
fs.existsSync(canonicalPath) &&
|
|
879
|
+
fs.existsSync(legacyPath);
|
|
483
880
|
for (const filePath of candidates) {
|
|
484
881
|
if (!filePath || !fs.existsSync(filePath))
|
|
485
882
|
continue;
|
|
@@ -491,7 +888,19 @@ export function loadConfigFile(input = {}) {
|
|
|
491
888
|
console.warn(`[opencode-codex-auth] Invalid codex-config at ${filePath}. ${validation.issues.join("; ")}`);
|
|
492
889
|
continue;
|
|
493
890
|
}
|
|
494
|
-
|
|
891
|
+
const result = parseConfigFileObjectWithMetadata(parsed);
|
|
892
|
+
if (result.deprecatedKeys.length > 0) {
|
|
893
|
+
console.warn(`[opencode-codex-auth] Deprecated config key(s) in ${filePath}: ${result.deprecatedKeys.join(", ")}. Use reasoningSummary, textVerbosity, and serviceTier: "auto" instead.`);
|
|
894
|
+
}
|
|
895
|
+
if (shouldQuarantineLegacyAfterCanonicalLoad &&
|
|
896
|
+
filePath === canonicalPath &&
|
|
897
|
+
legacyPath &&
|
|
898
|
+
fs.existsSync(legacyPath)) {
|
|
899
|
+
const quarantinedPath = quarantineLegacyConfigSync(legacyPath);
|
|
900
|
+
const suffix = quarantinedPath ? ` Quarantined legacy file to ${quarantinedPath}.` : "";
|
|
901
|
+
console.warn(`[opencode-codex-auth] Found both ${CONFIG_FILE} and ${LEGACY_CONFIG_FILE}. Using ${CONFIG_FILE}.${suffix}`);
|
|
902
|
+
}
|
|
903
|
+
return result.config;
|
|
495
904
|
}
|
|
496
905
|
catch (error) {
|
|
497
906
|
const detail = error instanceof Error ? error.message : String(error);
|