@bitkyc08/opencodex 2.25.0 → 2.26.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/bin/ocx.mjs +59 -7
- package/gui/dist/assets/index-RL6b1bTV.js +102 -0
- package/gui/dist/index.html +1 -1
- package/package.json +1 -1
- package/src/adapters/base.ts +18 -0
- package/src/adapters/client-fingerprint.ts +0 -2
- package/src/adapters/cursor/http1-bidi.ts +361 -0
- package/src/adapters/cursor/live-models.ts +117 -30
- package/src/adapters/cursor/live-transport.ts +137 -56
- package/src/adapters/cursor/native-exec-fs.ts +1 -1
- package/src/adapters/cursor/native-exec-network.ts +1 -1
- package/src/adapters/cursor/native-exec-shell.ts +0 -1
- package/src/adapters/cursor/protobuf-request.ts +89 -21
- package/src/adapters/cursor/tool-definitions.ts +18 -7
- package/src/adapters/cursor/tool-result-normalize.ts +92 -0
- package/src/adapters/cursor/transport.ts +7 -0
- package/src/adapters/cursor.ts +2 -0
- package/src/adapters/google-http.ts +38 -10
- package/src/adapters/google.ts +23 -3
- package/src/adapters/openai-chat.ts +38 -13
- package/src/adapters/openai-responses.ts +129 -9
- package/src/adapters/registry.ts +30 -1
- package/src/bridge.ts +50 -12
- package/src/chat/inbound.ts +1 -0
- package/src/claude/agents-inject.ts +3 -2
- package/src/cli/dispatch.ts +19 -6
- package/src/cli/help.ts +2 -1
- package/src/cli/integrations.ts +35 -0
- package/src/cli/minimax.ts +8 -2
- package/src/cli/registry.ts +13 -2
- package/src/clients/config-export.ts +120 -1
- package/src/codex/account-store.ts +17 -1
- package/src/codex/auth-api.ts +51 -17
- package/src/codex/catalog/effort.ts +8 -5
- package/src/codex/catalog/provider-fetch.ts +39 -27
- package/src/codex/catalog/sync.ts +30 -8
- package/src/codex/inject.ts +39 -13
- package/src/codex/main-account.ts +29 -1
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +25 -0
- package/src/codex/prompt-journal.ts +6 -2
- package/src/codex/quota-rejection.ts +21 -7
- package/src/codex/refresh.ts +4 -2
- package/src/codex/sync.ts +106 -3
- package/src/codex/warmup.ts +187 -81
- package/src/config.ts +85 -46
- package/src/generated/compatibility-version.json +127 -83
- package/src/grok/inject.ts +1 -1
- package/src/images/loop.ts +1 -0
- package/src/integrations/registry.ts +7 -0
- package/src/lab/automation/config-persistence.ts +2 -2
- package/src/lab/automation/persistence.ts +2 -2
- package/src/lab/ledger/purge.ts +2 -2
- package/src/lab/subject/behavior-fingerprint.ts +2 -2
- package/src/lib/config-ownership.ts +5 -2
- package/src/lib/destination-policy.ts +18 -1
- package/src/lib/provider-outbound.ts +7 -0
- package/src/lib/redact.ts +11 -0
- package/src/lib/tool-argument-integers.ts +50 -6
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-retry.ts +2 -1
- package/src/lib/windows-atomic-replace.ts +155 -0
- package/src/lib/windows-service-wrappers.ts +72 -0
- package/src/oauth/google-antigravity.ts +2 -2
- package/src/oauth/index.ts +60 -8
- package/src/providers/antigravity-models.ts +58 -4
- package/src/providers/command-code-efforts.ts +36 -9
- package/src/providers/context-cap.ts +9 -0
- package/src/providers/derive.ts +4 -0
- package/src/providers/fastwire.ts +453 -0
- package/src/providers/registry.ts +21 -1
- package/src/providers/service-tier.ts +173 -89
- package/src/responses/parser.ts +25 -16
- package/src/responses/reasoning-replay-cache.ts +30 -0
- package/src/responses/thought-signature-replay.ts +74 -4
- package/src/router.ts +6 -0
- package/src/routing/compatibility/behavior.ts +27 -16
- package/src/server/index.ts +10 -1
- package/src/server/management/oauth-account-routes.ts +10 -2
- package/src/server/management/shared.ts +1 -1
- package/src/server/management/system-routes.ts +15 -0
- package/src/server/request-log.ts +57 -3
- package/src/server/responses/agent-task-recovery.ts +6 -1
- package/src/server/responses/core.ts +209 -40
- package/src/server/responses/fetch-helpers.ts +15 -36
- package/src/server/responses/responses-field-backfill.ts +173 -0
- package/src/server/responses-reasoning-summary-rewrite.ts +171 -0
- package/src/service.ts +38 -36
- package/src/storage/cleanup.ts +2 -2
- package/src/tray/windows.ts +3 -2
- package/src/types.ts +101 -14
- package/src/update/job.ts +9 -18
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +259 -0
- package/src/usage/cost.ts +34 -5
- package/src/usage/log.ts +74 -4
- package/src/vision/anthropic-describe.ts +10 -6
- package/src/web-search/anthropic-executor.ts +8 -6
- package/gui/dist/assets/index-DxJ7kXj9.js +0 -102
package/src/oauth/index.ts
CHANGED
|
@@ -292,12 +292,56 @@ export class UnsupportedOAuthProviderError extends Error {
|
|
|
292
292
|
}
|
|
293
293
|
|
|
294
294
|
export class OAuthLoginRequiredError extends Error {
|
|
295
|
+
readonly provider: string;
|
|
296
|
+
|
|
295
297
|
constructor(provider: string) {
|
|
296
298
|
super(`Not logged in to ${provider}. Run: ocx login ${provider}`);
|
|
297
299
|
this.name = "OAuthLoginRequiredError";
|
|
300
|
+
this.provider = provider;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export class OAuthProviderPublicationError extends Error {
|
|
305
|
+
constructor() {
|
|
306
|
+
super("OAuth credential was saved, but the provider entry was not written. Resolve the account namespace collision, then retry login.");
|
|
307
|
+
this.name = "OAuthProviderPublicationError";
|
|
298
308
|
}
|
|
299
309
|
}
|
|
300
310
|
|
|
311
|
+
export class OAuthReauthIdentityMismatchError extends Error {
|
|
312
|
+
constructor() {
|
|
313
|
+
super("Signed-in account does not match the selected account. Sign in with the same account.");
|
|
314
|
+
this.name = "OAuthReauthIdentityMismatchError";
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export class OAuthReauthIdentityUnverifiedError extends Error {
|
|
319
|
+
constructor() {
|
|
320
|
+
super("Could not verify signed-in account identity for reauth.");
|
|
321
|
+
this.name = "OAuthReauthIdentityUnverifiedError";
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/** Project arbitrary OAuth failures onto the small, stable public error vocabulary. */
|
|
326
|
+
export function publicOAuthAuthenticationErrorMessage(error: unknown): string {
|
|
327
|
+
if (error instanceof OAuthMutationBusyError) {
|
|
328
|
+
return error.message === "OAuth mutation queue wait timed out"
|
|
329
|
+
? "OAuth mutation queue wait timed out"
|
|
330
|
+
: "OAuth mutation queue is busy";
|
|
331
|
+
}
|
|
332
|
+
if (
|
|
333
|
+
(error instanceof OAuthLoginRequiredError && isOAuthProvider(error.provider))
|
|
334
|
+
|| error instanceof OAuthProviderPublicationError
|
|
335
|
+
// Reauth identity outcomes carry fixed, account-free remediation text. Dropping them to the
|
|
336
|
+
// generic message hides WHICH failure the user must fix (sign in with the selected account).
|
|
337
|
+
|| error instanceof OAuthReauthIdentityMismatchError
|
|
338
|
+
|| error instanceof OAuthReauthIdentityUnverifiedError
|
|
339
|
+
|| error instanceof OAuthTokenRefreshBusyError
|
|
340
|
+
|| error instanceof OAuthTokenRefreshStaleError
|
|
341
|
+
) return error.message;
|
|
342
|
+
return "OAuth authentication failed. Check the OpenCodex account status and retry.";
|
|
343
|
+
}
|
|
344
|
+
|
|
301
345
|
function accessSnapshot(provider: string, accountId: string, cred: OAuthCredentials): OAuthAccessSnapshot {
|
|
302
346
|
const storedKiroRouting = {
|
|
303
347
|
...(cred.kiro?.profileArn ? { profileArn: cred.kiro.profileArn } : {}),
|
|
@@ -1111,7 +1155,7 @@ export async function runLogin(
|
|
|
1111
1155
|
const existing = getAccountCredential(provider, opts.reauthAccountId);
|
|
1112
1156
|
if (!existing) throw new Error(`Unknown account for reauth: ${opts.reauthAccountId}`);
|
|
1113
1157
|
if (!existing.accountId && !existing.email) {
|
|
1114
|
-
throw new
|
|
1158
|
+
throw new OAuthReauthIdentityUnverifiedError();
|
|
1115
1159
|
}
|
|
1116
1160
|
const identityMatches = existing.accountId && cred.accountId
|
|
1117
1161
|
? existing.accountId === cred.accountId
|
|
@@ -1119,7 +1163,7 @@ export async function runLogin(
|
|
|
1119
1163
|
? existing.email.toLowerCase() === cred.email.toLowerCase()
|
|
1120
1164
|
: false;
|
|
1121
1165
|
if (!identityMatches) {
|
|
1122
|
-
throw new
|
|
1166
|
+
throw new OAuthReauthIdentityMismatchError();
|
|
1123
1167
|
}
|
|
1124
1168
|
await (deps.saveAccountCredential ?? saveAccountCredential)(provider, opts.reauthAccountId, cred);
|
|
1125
1169
|
} else {
|
|
@@ -1136,10 +1180,7 @@ export async function runLogin(
|
|
|
1136
1180
|
provider,
|
|
1137
1181
|
);
|
|
1138
1182
|
if (lateCollision) {
|
|
1139
|
-
throw new
|
|
1140
|
-
`${lateCollision}. The credential for "${provider}" was saved, but the provider entry was not written. `
|
|
1141
|
-
+ "Rename the account selector, then re-run the login.",
|
|
1142
|
-
);
|
|
1183
|
+
throw new OAuthProviderPublicationError();
|
|
1143
1184
|
}
|
|
1144
1185
|
upsertOAuthProvider(latestConfig, provider);
|
|
1145
1186
|
saveLatestConfig(latestConfig);
|
|
@@ -1381,7 +1422,16 @@ export async function startLoginFlow(
|
|
|
1381
1422
|
onManualCodeInput: (expectedState?: string) => waitForManualLoginCode(provider, abort.signal, expectedState),
|
|
1382
1423
|
signal: abort.signal,
|
|
1383
1424
|
};
|
|
1425
|
+
const abandonIfNotOwner = (error?: unknown): boolean => {
|
|
1426
|
+
if (loginAbort.get(provider) === abort) return false;
|
|
1427
|
+
if (!urlResolved) reject(error ?? new Error("OAuth login was superseded"));
|
|
1428
|
+
return true;
|
|
1429
|
+
};
|
|
1384
1430
|
const settle = async (error?: unknown): Promise<void> => {
|
|
1431
|
+
// Cancellation deletes this controller and records its own terminal result. A late provider
|
|
1432
|
+
// rejection (or an older flow settling after a replacement starts) must not overwrite that
|
|
1433
|
+
// state or delete the replacement flow's controller/manual-code slot.
|
|
1434
|
+
if (abandonIfNotOwner(error)) return;
|
|
1385
1435
|
let finalError = error;
|
|
1386
1436
|
try {
|
|
1387
1437
|
await lifecycle?.onSettled?.();
|
|
@@ -1390,6 +1440,7 @@ export async function startLoginFlow(
|
|
|
1390
1440
|
// runtime config. For an already-failed login, keep the original recovery error.
|
|
1391
1441
|
if (finalError === undefined) finalError = settleError;
|
|
1392
1442
|
}
|
|
1443
|
+
if (abandonIfNotOwner(finalError)) return;
|
|
1393
1444
|
if (finalError === undefined) {
|
|
1394
1445
|
loginAbort.delete(provider);
|
|
1395
1446
|
clearManualCodeSlot(provider);
|
|
@@ -1403,7 +1454,7 @@ export async function startLoginFlow(
|
|
|
1403
1454
|
const e = finalError;
|
|
1404
1455
|
loginAbort.delete(provider);
|
|
1405
1456
|
clearManualCodeSlot(provider);
|
|
1406
|
-
const msg =
|
|
1457
|
+
const msg = publicOAuthAuthenticationErrorMessage(e);
|
|
1407
1458
|
loginState.set(provider, { done: true, error: msg });
|
|
1408
1459
|
if (!urlResolved) reject(e);
|
|
1409
1460
|
};
|
|
@@ -1414,9 +1465,10 @@ export async function startLoginFlow(
|
|
|
1414
1465
|
(e: unknown) => settle(e),
|
|
1415
1466
|
).catch((e: unknown) => {
|
|
1416
1467
|
// settle catches lifecycle failures, so this is only a defensive promise-boundary guard.
|
|
1468
|
+
if (abandonIfNotOwner(e)) return;
|
|
1417
1469
|
loginAbort.delete(provider);
|
|
1418
1470
|
clearManualCodeSlot(provider);
|
|
1419
|
-
const msg =
|
|
1471
|
+
const msg = publicOAuthAuthenticationErrorMessage(e);
|
|
1420
1472
|
loginState.set(provider, { done: true, error: msg });
|
|
1421
1473
|
if (!urlResolved) reject(e);
|
|
1422
1474
|
});
|
|
@@ -78,9 +78,6 @@ function pickerModelIdForDiscoveredWireId(
|
|
|
78
78
|
info: Record<string, unknown>,
|
|
79
79
|
available: ReadonlyMap<string, Record<string, unknown>>,
|
|
80
80
|
): string {
|
|
81
|
-
const displayModelId = antigravityDisplayModelId(info.displayName, wireId);
|
|
82
|
-
if (displayModelId) return displayModelId;
|
|
83
|
-
|
|
84
81
|
const explicitPickerId = Object.hasOwn(ANTIGRAVITY_PICKER_MODEL_BY_WIRE_ID, wireId)
|
|
85
82
|
? ANTIGRAVITY_PICKER_MODEL_BY_WIRE_ID[wireId]
|
|
86
83
|
: undefined;
|
|
@@ -107,9 +104,35 @@ function pickerModelIdForDiscoveredWireId(
|
|
|
107
104
|
return baseId;
|
|
108
105
|
}
|
|
109
106
|
}
|
|
107
|
+
|
|
108
|
+
// Display labels are a LAST resort, never a first one. CCA labels a tier row
|
|
109
|
+
// "Gemini 3.7 Flash (High)", which slugs to `gemini-3.7-flash-high` — a per-tier
|
|
110
|
+
// picker row that re-splits exactly the ladder the collapse rules above just
|
|
111
|
+
// joined, and that carries no effort ladder of its own. Consulting the label
|
|
112
|
+
// first (the #1897 regression) turned every collapsed base model back into three
|
|
113
|
+
// suffix rows and stripped reasoning-effort control from the picker.
|
|
114
|
+
//
|
|
115
|
+
// The label still earns its keep where nothing else can speak: an id Google has
|
|
116
|
+
// renamed on the wire while keeping a stable public name.
|
|
117
|
+
const displayModelId = antigravityDisplayModelId(info.displayName, wireId);
|
|
118
|
+
if (displayModelId && !collapsesIntoKnownPickerModel(displayModelId)) return displayModelId;
|
|
119
|
+
|
|
110
120
|
return wireId;
|
|
111
121
|
}
|
|
112
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Whether a display-derived id is really a tier of a picker-visible base model.
|
|
125
|
+
*
|
|
126
|
+
* `gemini-3.7-flash-high` looks like a model id and is not one: it is the "high"
|
|
127
|
+
* rung of `gemini-3.7-flash`, whose ladder lives in ANTIGRAVITY_MODEL_EFFORTS.
|
|
128
|
+
* Publishing it as its own row is what breaks effort selection.
|
|
129
|
+
*/
|
|
130
|
+
function collapsesIntoKnownPickerModel(candidateId: string): boolean {
|
|
131
|
+
const effortMatch = /^(.*)-(low|medium|high)$/.exec(candidateId);
|
|
132
|
+
const baseId = effortMatch?.[1];
|
|
133
|
+
return baseId !== undefined && isKnownAntigravityPickerModelId(baseId);
|
|
134
|
+
}
|
|
135
|
+
|
|
113
136
|
// ── Effort ladders per collapsed base model ──
|
|
114
137
|
// Gemini models: effort → wire model suffix (official agy UI pattern).
|
|
115
138
|
// Claude Opus: effort → thinkingConfig.thinkingLevel (CLIProxyAPI proven pattern).
|
|
@@ -389,6 +412,16 @@ export function parseAntigravityAvailableModels(
|
|
|
389
412
|
}
|
|
390
413
|
}
|
|
391
414
|
}
|
|
415
|
+
// This model is exposed by Antigravity's agent chat surface even though the discovery
|
|
416
|
+
// response groups it under image generation, so it never appears in agentModelSorts.
|
|
417
|
+
if (Array.isArray(body.imageGenerationModelIds)
|
|
418
|
+
&& body.imageGenerationModelIds.includes("gemini-3.1-flash-image")
|
|
419
|
+
&& Object.hasOwn(models, "gemini-3.1-flash-image")
|
|
420
|
+
&& antigravityRecord(models["gemini-3.1-flash-image"])
|
|
421
|
+
&& !ids.includes("gemini-3.1-flash-image")) {
|
|
422
|
+
if (ids.length >= limit) return null;
|
|
423
|
+
ids.push("gemini-3.1-flash-image");
|
|
424
|
+
}
|
|
392
425
|
// Newer CCA responses identify tiered Flash models through this index instead of
|
|
393
426
|
// adding their synthetic wire ids to agentModelSorts.
|
|
394
427
|
const tieredModelIds = antigravityRecord(body.tieredModelIds);
|
|
@@ -413,6 +446,16 @@ export function parseAntigravityAvailableModels(
|
|
|
413
446
|
for (const wireId of ids) {
|
|
414
447
|
const info = antigravityRecord(models[wireId]);
|
|
415
448
|
if (!info || available.has(wireId)) continue;
|
|
449
|
+
// Compatibility aliases are deliberately routed to NEWER wire ids for saved
|
|
450
|
+
// selections. CCA keeps serving retired generations (3.5/3.6 Flash tiers) in its
|
|
451
|
+
// agent list long after they stop being the model anyone should pick, so admitting
|
|
452
|
+
// them as independently discovered rows republishes exactly the dead tiers the
|
|
453
|
+
// alias map exists to retire. Routing for a saved id still works — it resolves
|
|
454
|
+
// through ANTIGRAVITY_MODEL_ALIASES — it just no longer gets its own picker row.
|
|
455
|
+
const alias = Object.hasOwn(ANTIGRAVITY_MODEL_ALIASES, wireId)
|
|
456
|
+
? ANTIGRAVITY_MODEL_ALIASES[wireId]
|
|
457
|
+
: undefined;
|
|
458
|
+
if (alias && alias !== wireId) continue;
|
|
416
459
|
available.set(wireId, info);
|
|
417
460
|
}
|
|
418
461
|
|
|
@@ -479,7 +522,18 @@ export function resolveAntigravityEffortWireModel(
|
|
|
479
522
|
effort?: string,
|
|
480
523
|
baseUrl?: string,
|
|
481
524
|
): { wireModelId: string; thinkingLevel?: string } {
|
|
482
|
-
|
|
525
|
+
// A collapsed picker row reports ONE representative wire id (whichever tier CCA
|
|
526
|
+
// listed first), so live discovery cannot describe a ladder — it can only name a
|
|
527
|
+
// single rung. Letting it answer for a base model we already have a ladder for
|
|
528
|
+
// collapses every effort onto that one rung: `gemini-3.1-pro` low and high both
|
|
529
|
+
// became `gemini-pro-agent`, and `gemini-3.7-flash` sent thinkingLevel=low against
|
|
530
|
+
// the `-high` wire id, a request that contradicts itself. Rules 1b/2/3 below own
|
|
531
|
+
// these models; discovery answers only for ids no rule knows.
|
|
532
|
+
const hasOwnEffortLadder = Object.hasOwn(ANTIGRAVITY_THINKING_LEVEL_MODELS, modelId)
|
|
533
|
+
|| Object.hasOwn(ANTIGRAVITY_EFFORT_WIRE_MAP, modelId);
|
|
534
|
+
const discoveredWireModelId = hasOwnEffortLadder
|
|
535
|
+
? undefined
|
|
536
|
+
: discoveredAntigravityWireModelId(modelId, baseUrl);
|
|
483
537
|
if (discoveredWireModelId && (discoveredWireModelId !== modelId || isAntigravitySuffixModelId(modelId))) {
|
|
484
538
|
const defaultLevel = ANTIGRAVITY_THINKING_LEVEL_MODELS[modelId];
|
|
485
539
|
return {
|
|
@@ -9,14 +9,31 @@ const COMMAND_CODE_MODEL_EFFORTS = {
|
|
|
9
9
|
efforts: ["high", "max"],
|
|
10
10
|
profileUrl: "https://commandcode.ai/models/deepseek-v4-flash",
|
|
11
11
|
},
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
// Keys must match the EXACT upstream /provider/v1/models ids (GLM ships as
|
|
13
|
+
// `zai-org/GLM-5.3`, not `zai-org/glm-5.3`). The table doubles as the router's
|
|
14
|
+
// known-ids decode source (via `knownModelIdsForProvider`), so a case mismatch
|
|
15
|
+
// makes the Codex-facing slug `commandcode/zai-org-GLM-5.3` pass through
|
|
16
|
+
// undecoded and upstream rejects it with `unsupported_model`.
|
|
17
|
+
"zai-org/GLM-5": {
|
|
18
|
+
efforts: ["high", "max"],
|
|
19
|
+
profileUrl: "https://commandcode.ai/models/glm-5",
|
|
15
20
|
},
|
|
16
|
-
"zai-org/
|
|
21
|
+
"zai-org/GLM-5.1": {
|
|
22
|
+
efforts: ["high", "max"],
|
|
23
|
+
profileUrl: "https://commandcode.ai/models/glm-5-1",
|
|
24
|
+
},
|
|
25
|
+
"zai-org/GLM-5.2": {
|
|
17
26
|
efforts: ["high", "max"],
|
|
18
27
|
profileUrl: "https://commandcode.ai/models/glm-5-2",
|
|
19
28
|
},
|
|
29
|
+
"zai-org/GLM-5.2-Fast": {
|
|
30
|
+
efforts: ["high", "max"],
|
|
31
|
+
profileUrl: "https://commandcode.ai/models/glm-5-2-fast",
|
|
32
|
+
},
|
|
33
|
+
"zai-org/GLM-5.3": {
|
|
34
|
+
efforts: ["low", "high", "max"],
|
|
35
|
+
profileUrl: "https://commandcode.ai/models/glm-5-3",
|
|
36
|
+
},
|
|
20
37
|
// Muse Spark: CLI currently prints "has no adjustable reasoning effort" and
|
|
21
38
|
// blocks --effort locally, but the upstream /alpha/generate endpoint accepts
|
|
22
39
|
// reasoning_effort low..max for meta/muse-spark-1.2-contributor (verified
|
|
@@ -53,8 +70,14 @@ function keyFor(modelId: string): string {
|
|
|
53
70
|
|
|
54
71
|
export function commandCodeReasoningEfforts(modelId: string): readonly string[] | undefined {
|
|
55
72
|
const key = keyFor(modelId);
|
|
56
|
-
|
|
57
|
-
|
|
73
|
+
const refreshed = refreshedEfforts.get(key);
|
|
74
|
+
if (refreshed !== undefined) return refreshed;
|
|
75
|
+
// Case-insensitive: the table keys match the EXACT upstream ids (e.g. `zai-org/GLM-5.3`),
|
|
76
|
+
// but callers may pass either case.
|
|
77
|
+
for (const [id, efforts] of Object.entries(COMMAND_CODE_MODEL_REASONING_EFFORTS)) {
|
|
78
|
+
if (keyFor(id) === key) return efforts;
|
|
79
|
+
}
|
|
80
|
+
return undefined;
|
|
58
81
|
}
|
|
59
82
|
|
|
60
83
|
function parsedProfileEfforts(page: string): string[] | undefined {
|
|
@@ -82,9 +105,13 @@ export async function refreshCommandCodeReasoningEfforts(
|
|
|
82
105
|
fetchFn: typeof globalThis.fetch = globalThis.fetch,
|
|
83
106
|
): Promise<readonly string[] | undefined> {
|
|
84
107
|
const key = keyFor(modelId);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
108
|
+
let profile: { efforts: readonly string[]; profileUrl: string } | undefined;
|
|
109
|
+
for (const [id, row] of Object.entries(COMMAND_CODE_MODEL_EFFORTS)) {
|
|
110
|
+
if (keyFor(id) === key) {
|
|
111
|
+
profile = row;
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
88
115
|
if (!profile) return undefined;
|
|
89
116
|
try {
|
|
90
117
|
const response = await fetchFn(profile.profileUrl, {
|
|
@@ -27,6 +27,15 @@ export function applyProviderContextCap(contextWindow: number | undefined, cap:
|
|
|
27
27
|
return contextWindow > cap ? cap : contextWindow;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* 上游没报窗口时,已开启的 Context cap 就是实际窗口。
|
|
32
|
+
* 128k 只是 Codex 解析器的兼容底线,不能当成“已发现窗口”再拿去和 cap 做 min。
|
|
33
|
+
*/
|
|
34
|
+
export function resolveUnknownRoutedContextWindow(cap: number | undefined): number {
|
|
35
|
+
const window = isValidContextCap(cap) ? Math.floor(cap) : 0;
|
|
36
|
+
return window > 0 ? window : 128_000;
|
|
37
|
+
}
|
|
38
|
+
|
|
30
39
|
/** Effective global cap value: explicit config value, else the built-in default. */
|
|
31
40
|
export function globalContextCapValue(config: Pick<OcxConfig, "contextCapValue">): number {
|
|
32
41
|
const value = config.contextCapValue;
|
package/src/providers/derive.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CodexAccountMode, OcxProviderConfig } from "../types";
|
|
2
|
+
import { cloneFastWire } from "./fastwire";
|
|
2
3
|
import {
|
|
3
4
|
PROVIDER_REGISTRY,
|
|
4
5
|
registryEntryForProviderDestination,
|
|
@@ -459,6 +460,9 @@ export function enrichProviderFromRegistry(name: string, prov: OcxProviderConfig
|
|
|
459
460
|
}
|
|
460
461
|
// Registry-only metadata (never seeded into saved config): backfill straight from
|
|
461
462
|
// the entry so an explicit user value stays distinguishable from the default.
|
|
463
|
+
if (prov.fastWire === undefined && entry.fastWire !== undefined) {
|
|
464
|
+
prov.fastWire = cloneFastWire(entry.fastWire);
|
|
465
|
+
}
|
|
462
466
|
if (prov.supportsServiceTier === undefined && entry.supportsServiceTier !== undefined) prov.supportsServiceTier = entry.supportsServiceTier;
|
|
463
467
|
if (prov.preserveResponsesReasoningContent === undefined && entry.preserveResponsesReasoningContent !== undefined) prov.preserveResponsesReasoningContent = entry.preserveResponsesReasoningContent;
|
|
464
468
|
applyReasoningSummaryDefaults(prov, entry.modelSupportsReasoningSummaries);
|