@bitkyc08/opencodex 2.37.0 → 2.39.0-preview.20260901
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 +127 -16
- package/gui/dist/assets/index-6HZDkIpX.js +112 -0
- package/gui/dist/assets/index-uvENYLin.css +1 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/aside.svg +3 -0
- package/gui/dist/provider-icons/baseten.svg +13 -0
- package/gui/dist/provider-icons/bizrouter.svg +41 -0
- package/gui/dist/provider-icons/cerebras.svg +26 -0
- package/gui/dist/provider-icons/deepinfra.svg +75 -0
- package/gui/dist/provider-icons/deepseek-harness.svg +3 -0
- package/gui/dist/provider-icons/digitalocean.svg +10 -0
- package/gui/dist/provider-icons/featherless.svg +4 -0
- package/gui/dist/provider-icons/gajae-code.svg +410 -0
- package/gui/dist/provider-icons/hermes-agent.svg +207 -0
- package/gui/dist/provider-icons/hyperbolic.svg +18 -0
- package/gui/dist/provider-icons/kilo.svg +13 -0
- package/gui/dist/provider-icons/litellm.svg +1 -0
- package/gui/dist/provider-icons/minimax.svg +1 -0
- package/gui/dist/provider-icons/nanogpt.svg +74 -0
- package/gui/dist/provider-icons/nebius.svg +1 -0
- package/gui/dist/provider-icons/neuralwatt.svg +27 -0
- package/gui/dist/provider-icons/nous.svg +149 -0
- package/gui/dist/provider-icons/novita.svg +32 -0
- package/gui/dist/provider-icons/oh-my-pi.svg +11 -0
- package/gui/dist/provider-icons/openclaw.svg +54 -0
- package/gui/dist/provider-icons/orcarouter.svg +175 -0
- package/gui/dist/provider-icons/parallel.svg +13 -0
- package/gui/dist/provider-icons/prime-agent.svg +21 -0
- package/gui/dist/provider-icons/sambanova.svg +276 -0
- package/gui/dist/provider-icons/scaleway.svg +11 -0
- package/gui/dist/provider-icons/siliconflow.svg +18 -0
- package/gui/dist/provider-icons/synthetic.svg +12 -0
- package/gui/dist/provider-icons/together.svg +18 -0
- package/gui/dist/provider-icons/umans.svg +30 -0
- package/gui/dist/provider-icons/venice.svg +165 -0
- package/gui/dist/provider-icons/vultr.svg +15 -0
- package/gui/dist/provider-icons/zai.svg +218 -0
- package/gui/dist/provider-icons/zcode.svg +219 -0
- package/gui/dist/provider-icons/zenmux.svg +1 -0
- package/package.json +1 -1
- package/src/adapters/cursor/live-models.ts +1 -0
- package/src/adapters/cursor/protobuf-request.ts +4 -1
- package/src/adapters/cursor/tool-definitions.ts +36 -4
- package/src/adapters/openai-responses.ts +72 -10
- package/src/bridge.ts +15 -15
- package/src/cli/capabilities.ts +14 -0
- package/src/cli/codex-cli-update.ts +96 -0
- package/src/cli/codex-shim-autorestore.ts +3 -0
- package/src/cli/dispatch.ts +54 -18
- package/src/cli/export-command.ts +18 -17
- package/src/cli/help.ts +2 -2
- package/src/cli/index.ts +423 -32
- package/src/cli/integrations.ts +24 -2
- package/src/cli/launcher-context.ts +53 -2
- package/src/cli/opencode.ts +126 -33
- package/src/cli/registry.ts +16 -10
- package/src/cli/system-command.ts +6 -1
- package/src/cli/uninstall-plan.ts +86 -0
- package/src/clients/config-export.ts +293 -28
- package/src/codex/account-store.ts +131 -12
- package/src/codex/auth-api.ts +202 -33
- package/src/codex/autostart-health.ts +3 -3
- package/src/codex/catalog/provider-fetch.ts +96 -10
- package/src/codex/catalog/sync.ts +4 -3
- package/src/codex/cli-install-provenance.ts +795 -0
- package/src/codex/convergence.ts +4 -3
- package/src/codex/credential-mutation-epoch.ts +11 -0
- package/src/codex/history-job.ts +10 -0
- package/src/codex/history-manifest.ts +35 -2
- package/src/codex/history-provider.ts +196 -19
- package/src/codex/history-worker.ts +3 -0
- package/src/codex/main-account.ts +2 -0
- package/src/codex/model-entitlements.ts +430 -27
- package/src/codex/native-profile-manager.ts +4 -0
- package/src/codex/quota-401-recovery.ts +190 -0
- package/src/codex/quota-recovery-timing.ts +28 -0
- package/src/codex/quota.ts +6 -0
- package/src/codex/reset-credit-operation-ledger.ts +1411 -0
- package/src/codex/reset-credit-recovery.ts +20 -2
- package/src/codex/routing.ts +68 -16
- package/src/codex/shim.ts +204 -18
- package/src/codex/subagent-model-fallback.ts +4 -1
- package/src/codex/user-identity.ts +2 -1
- package/src/config/paths.ts +18 -3
- package/src/config/pending-teardown-names.d.mts +8 -0
- package/src/config/pending-teardown-names.mjs +69 -0
- package/src/config/pending-teardown.ts +286 -0
- package/src/config.ts +23 -0
- package/src/generated/compatibility-version.json +155 -67
- package/src/integrations/journal.ts +12 -1
- package/src/integrations/registry.ts +112 -0
- package/src/integrations/state.ts +67 -5
- package/src/integrations/writer.ts +107 -16
- package/src/lib/bounded-subprocess.ts +36 -0
- package/src/lib/process-control.ts +30 -5
- package/src/lib/state-store-registrations.ts +8 -0
- package/src/lib/strict-semver.ts +47 -0
- package/src/lib/windows-elevation.ts +32 -1
- package/src/lib/windows-secret-acl.ts +47 -25
- package/src/lib/windows-service-mutation-lock.ts +133 -0
- package/src/lib/windows-user-principal.ts +15 -17
- package/src/oauth/index.ts +220 -13
- package/src/oauth/store.ts +220 -18
- package/src/responses/spill-store.ts +354 -29
- package/src/responses/state.ts +775 -8
- package/src/server/index.ts +4 -3
- package/src/server/lifecycle.ts +5 -1
- package/src/server/management/integration-routes.ts +36 -5
- package/src/server/management/model-rows.ts +11 -2
- package/src/server/management/provider-routes.ts +4 -0
- package/src/server/management/system-restart.ts +5 -5
- package/src/server/management-api.ts +72 -13
- package/src/server/responses/encrypted-payload.ts +18 -1
- package/src/server/startup-action-control.ts +3 -2
- package/src/server/stop-teardown.ts +84 -0
- package/src/service.ts +749 -53
- package/src/sidecar/candidates.ts +1 -1
- package/src/update/codex-cli-update-launch-policy.d.mts +18 -0
- package/src/update/codex-cli-update-launch-policy.mjs +30 -0
- package/src/update/index.ts +39 -6
- package/src/update/job.ts +10 -11
- package/src/update/proxy-liveness-probe.d.mts +6 -0
- package/src/update/proxy-liveness-probe.mjs +84 -0
- package/src/update/stop-contract.d.mts +2 -0
- package/src/update/stop-contract.mjs +15 -0
- package/src/update/stop-decision.d.mts +10 -0
- package/src/update/stop-decision.mjs +34 -0
- package/src/vision/eligibility.ts +19 -1
- package/src/vision/index.ts +4 -18
- package/gui/dist/assets/index-CowztZdo.js +0 -112
- package/gui/dist/assets/index-jqE_VOKI.css +0 -1
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
import type { OcxConfig, OcxProviderConfig } from "../../types";
|
|
31
31
|
import { modelInList } from "../../types";
|
|
32
32
|
import { CODEX_REASONING_LEVELS, codexEffortRank, configuredReasoningEfforts, modelRecordValue, sanitizeCodexReasoningEfforts } from "../../reasoning-effort";
|
|
33
|
+
import { isModelVisionSidecarConsumer } from "../../vision/eligibility";
|
|
33
34
|
import { getModelMetadata, getModelMetadataCaseInsensitive, listModelMetadata, resolveMetadataProvider } from "../../generated/model-metadata";
|
|
34
35
|
import { enrichProviderFromRegistry, shouldCaseFoldMetadataModelId } from "../../providers/derive";
|
|
35
36
|
import {
|
|
@@ -42,6 +43,7 @@ import { effectiveGoogleMode, getProviderRegistryEntry, providerMatchesRegistryT
|
|
|
42
43
|
import { parseAntigravityAvailableModels, registerAntigravityDiscoveredWireModels } from "../../providers/antigravity-models";
|
|
43
44
|
import { applyProviderContextCap, providerContextCap, resolveUnknownRoutedContextWindow } from "../../providers/context-cap";
|
|
44
45
|
import { clampAutoCompactTokenLimit } from "../../providers/auto-compact-budget";
|
|
46
|
+
import { effectiveModelAliases } from "../../providers/default-aliases";
|
|
45
47
|
import { routedSlug, slugEquals, slugEquivalenceKey, slugsEquivalent } from "../../providers/slug-codec";
|
|
46
48
|
import { CODEX_GPT5_IDENTITY_LINE } from "../../adapters/identity";
|
|
47
49
|
import { filterCursorConfiguredModelsByLiveDiscovery } from "../../adapters/cursor/discovery";
|
|
@@ -669,11 +671,14 @@ export function applyProviderConfigHints(name: string, prov: OcxProviderConfig,
|
|
|
669
671
|
const configuredMaxInput = configuredMaxInputTokens(prov, model.id);
|
|
670
672
|
const configuredAutoCompact = configuredAutoCompactTokenLimit(prov, model.id);
|
|
671
673
|
let inputModalities = configuredInputModalities(prov, model.id);
|
|
672
|
-
//
|
|
673
|
-
//
|
|
674
|
+
// The shared vision-sidecar consumer predicate keeps catalog advertisement and request-time
|
|
675
|
+
// planning aligned. The catalog must still advertise image input — the Codex app
|
|
674
676
|
// gates attachments client-side on input_modalities, and a text-only entry would block images
|
|
675
|
-
// before the sidecar ever runs ("This model does not support image inputs").
|
|
676
|
-
|
|
677
|
+
// before the sidecar ever runs ("This model does not support image inputs"). Discovery-derived
|
|
678
|
+
// text-only rows stay untouched: the runtime predicate only reads these two config sources, so
|
|
679
|
+
// it would not convert those.
|
|
680
|
+
const sidecarCovered = isModelVisionSidecarConsumer(prov, model.id);
|
|
681
|
+
if (sidecarCovered) {
|
|
677
682
|
const base = inputModalities ?? model.inputModalities ?? ["text"];
|
|
678
683
|
inputModalities = base.includes("image") ? [...base] : [...base, "image"];
|
|
679
684
|
}
|
|
@@ -935,9 +940,70 @@ export function resolveComboCatalogMember(
|
|
|
935
940
|
};
|
|
936
941
|
}
|
|
937
942
|
|
|
943
|
+
const DATED_VARIANT_YYYYMMDD = /^(\d{4})(\d{2})(\d{2})$/;
|
|
944
|
+
const DATED_VARIANT_YYMMDD = /^(2\d)(\d{2})(\d{2})$/;
|
|
945
|
+
const DATED_VARIANT_MMDD_OR_YYMM = /^(\d{2})(\d{2})$/;
|
|
946
|
+
|
|
947
|
+
/** Whether a Gregorian year contains February 29th. */
|
|
948
|
+
function isLeapYear(year: number): boolean {
|
|
949
|
+
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
/**
|
|
953
|
+
* Whether a month/day pair exists in the given year. Without a year, February 29th is
|
|
954
|
+
* accepted because it occurs in at least one calendar year.
|
|
955
|
+
*/
|
|
956
|
+
function isValidCalendarDate(year: number | undefined, month: number, day: number): boolean {
|
|
957
|
+
if (year !== undefined && (year < 1 || year > 9999)) return false;
|
|
958
|
+
if (month < 1 || month > 12 || day < 1) return false;
|
|
959
|
+
const daysInMonth = [
|
|
960
|
+
31, year === undefined || isLeapYear(year) ? 29 : 28, 31, 30, 31, 30,
|
|
961
|
+
31, 31, 30, 31, 30, 31,
|
|
962
|
+
];
|
|
963
|
+
return day <= daysInMonth[month - 1]!;
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
/**
|
|
967
|
+
* Release-date suffixes providers actually publish: `YYYYMMDD` (`-20251001`), `YYMMDD`
|
|
968
|
+
* (`-260806`), `MMDD` (`-0813`) and `YYMM` (`-2512`). A `\d{8}`-only rule matched none of
|
|
969
|
+
* the dated ids on a real multi-provider install, so DeepSeek, Kimi, Mistral, Qwen and
|
|
970
|
+
* Solar aliases all fell through to `droppedConfiguredIds` (#3024).
|
|
971
|
+
*
|
|
972
|
+
* Calendar validation rejects impossible month-end and leap-day values as well as ordinary
|
|
973
|
+
* numeric suffixes such as `-2048`, `-4096` and `-8192`. `-1024` is the one irreducible
|
|
974
|
+
* collision — it is a valid `MMDD` (October 24th) — so it reads as dated. That is a known,
|
|
975
|
+
* accepted cost; the test table pins it so it cannot become a surprise later.
|
|
976
|
+
*
|
|
977
|
+
* Hyphenated ISO suffixes (`-2024-08-06`, `-05-06`) are deliberately out of scope: a
|
|
978
|
+
* hyphenated suffix is ambiguous against ordinary name segments and needs its own call.
|
|
979
|
+
*/
|
|
980
|
+
function isDatedVariantSuffix(suffix: string): boolean {
|
|
981
|
+
const yyyyMmDd = DATED_VARIANT_YYYYMMDD.exec(suffix);
|
|
982
|
+
if (yyyyMmDd) {
|
|
983
|
+
return isValidCalendarDate(
|
|
984
|
+
Number(yyyyMmDd[1]), Number(yyyyMmDd[2]), Number(yyyyMmDd[3]),
|
|
985
|
+
);
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
const yyMmDd = DATED_VARIANT_YYMMDD.exec(suffix);
|
|
989
|
+
if (yyMmDd) {
|
|
990
|
+
return isValidCalendarDate(
|
|
991
|
+
2000 + Number(yyMmDd[1]), Number(yyMmDd[2]), Number(yyMmDd[3]),
|
|
992
|
+
);
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
const mmDdOrYyMm = DATED_VARIANT_MMDD_OR_YYMM.exec(suffix);
|
|
996
|
+
if (!mmDdOrYyMm) return false;
|
|
997
|
+
const first = Number(mmDdOrYyMm[1]);
|
|
998
|
+
const second = Number(mmDdOrYyMm[2]);
|
|
999
|
+
return isValidCalendarDate(undefined, first, second)
|
|
1000
|
+
|| (first >= 20 && first <= 29 && second >= 1 && second <= 12);
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
/** Whether `liveId` is a supported dated release of the configured base id. */
|
|
938
1004
|
export function isDatedVariantId(liveId: string, configuredId: string): boolean {
|
|
939
1005
|
if (!liveId.startsWith(`${configuredId}-`)) return false;
|
|
940
|
-
return
|
|
1006
|
+
return isDatedVariantSuffix(liveId.slice(configuredId.length + 1));
|
|
941
1007
|
}
|
|
942
1008
|
|
|
943
1009
|
export const lastDropWarnSignature = new Map<string, string>();
|
|
@@ -2112,9 +2178,10 @@ async function gatherRoutedModelsUncached(
|
|
|
2112
2178
|
...(base.codexToolMode === undefined && replaced.codexToolMode !== undefined ? { codexToolMode: replaced.codexToolMode } : {}),
|
|
2113
2179
|
...(base.capabilities === undefined && replaced.capabilities !== undefined ? { capabilities: replaced.capabilities } : {}),
|
|
2114
2180
|
} : base;
|
|
2115
|
-
// Vision-sidecar coverage
|
|
2116
|
-
// noVisionModels, advertise image input so the
|
|
2117
|
-
// (#349/#344). Deliberately NOT the full
|
|
2181
|
+
// Vision-sidecar coverage only: when the enriched provider's shared predicate matches
|
|
2182
|
+
// noVisionModels or text-without-image modelInputModalities, advertise image input so the
|
|
2183
|
+
// Codex app lets images reach the sidecar (#349/#344). Deliberately NOT the full
|
|
2184
|
+
// applyProviderConfigHints pass — custom rows are a
|
|
2118
2185
|
// user override, so their explicit contextWindow / inputModalities / reasoning fields must be
|
|
2119
2186
|
// preserved verbatim (the hint pass would cap context and overwrite modalities from registry).
|
|
2120
2187
|
const mergedContext = typeof merged.contextWindow === "number" && merged.contextWindow > 0
|
|
@@ -2140,7 +2207,8 @@ async function gatherRoutedModelsUncached(
|
|
|
2140
2207
|
}
|
|
2141
2208
|
: mergedWithHardBounds;
|
|
2142
2209
|
const enrichedProvider = enrichedByName.get(cm.provider) ?? rawProvider;
|
|
2143
|
-
|
|
2210
|
+
// Reuse the request-time consumer predicate so custom rows cannot drift from catalog hints.
|
|
2211
|
+
if (enrichedProvider && isModelVisionSidecarConsumer(enrichedProvider, mergedWithAutoCompact.id)) {
|
|
2144
2212
|
const current = mergedWithAutoCompact.inputModalities ?? ["text"];
|
|
2145
2213
|
if (!current.includes("image")) {
|
|
2146
2214
|
return { ...mergedWithAutoCompact, inputModalities: [...current, "image"] };
|
|
@@ -2151,6 +2219,21 @@ async function gatherRoutedModelsUncached(
|
|
|
2151
2219
|
// Custom rows override discovered rows that encode to the same Codex-facing slug.
|
|
2152
2220
|
const customKeys = new Set(customModels.map(c => routedSlug(c.provider, c.id)));
|
|
2153
2221
|
const deduped = all.filter(m => !customKeys.has(routedSlug(m.provider, m.id)));
|
|
2222
|
+
const models = [...deduped, ...customModels];
|
|
2223
|
+
// ponytail: catalog-scale scan; index ids by provider if catalog growth makes this measurable.
|
|
2224
|
+
const aliasDisplayNames = new Map(activeProviders.flatMap(({ name, provider }) => {
|
|
2225
|
+
const providerModels = models.filter(model => model.provider === name);
|
|
2226
|
+
const aliases = [...effectiveModelAliases(config, provider, providerModels.map(model => model.id))];
|
|
2227
|
+
return aliases.flatMap(([id, { alias }]) => {
|
|
2228
|
+
const exact = providerModels.filter(model => model.id === id);
|
|
2229
|
+
const matches = exact.length > 0
|
|
2230
|
+
? exact
|
|
2231
|
+
: providerModels.filter(model => model.id.toLowerCase() === id.toLowerCase());
|
|
2232
|
+
return matches.length === 1
|
|
2233
|
+
? [[`${name}/${matches[0]!.id}`, `${provider.alias || name}/${alias}`] as const]
|
|
2234
|
+
: [];
|
|
2235
|
+
});
|
|
2236
|
+
}));
|
|
2154
2237
|
const providerModelOutcomes = providerResults.map(result => (
|
|
2155
2238
|
result.outcome.provider === OPENAI_API_PROVIDER_ID
|
|
2156
2239
|
&& capture.openAiApiPolicy.state === "captured"
|
|
@@ -2159,7 +2242,10 @@ async function gatherRoutedModelsUncached(
|
|
|
2159
2242
|
: result.outcome
|
|
2160
2243
|
));
|
|
2161
2244
|
return {
|
|
2162
|
-
models:
|
|
2245
|
+
models: models.map(model => {
|
|
2246
|
+
const displayName = aliasDisplayNames.get(`${model.provider}/${model.id}`);
|
|
2247
|
+
return displayName && !model.displayName ? { ...model, displayName } : model;
|
|
2248
|
+
}),
|
|
2163
2249
|
comboOmissions: localOmissions,
|
|
2164
2250
|
providerAuthOutcomes: localProviderAuthOutcomes,
|
|
2165
2251
|
providerModelOutcomes,
|
|
@@ -35,6 +35,7 @@ import { codexAccountNamespaceEntries, isMainCodexAccountTarget } from "../accou
|
|
|
35
35
|
import { MAIN_CODEX_ACCOUNT_ID } from "../main-account";
|
|
36
36
|
import {
|
|
37
37
|
availableAccountGatedNativeModels,
|
|
38
|
+
codexModelEntitlementStateForAccount,
|
|
38
39
|
isCodexModelEntitlementSnapshotCurrent,
|
|
39
40
|
resolveCodexModelEntitlements,
|
|
40
41
|
type CodexModelEntitlementSnapshot,
|
|
@@ -1613,10 +1614,10 @@ function writeRetainedCatalogSync({
|
|
|
1613
1614
|
? new Map([...accountBoundNativeOpenAiSlugsBySelector(config, observedAccountNativeEntries)].map(([selector, slugs]) => {
|
|
1614
1615
|
const target = accountTargets.get(selector);
|
|
1615
1616
|
const accountId = target && isMainCodexAccountTarget(target) ? MAIN_CODEX_ACCOUNT_ID : target;
|
|
1616
|
-
const entitled = accountId ? modelEntitlements.modelsByAccount.get(accountId) : undefined;
|
|
1617
|
-
const confirmed = accountId ? modelEntitlements.confirmedAccountIds.has(accountId) : false;
|
|
1618
1617
|
return [selector, slugs.filter(slug => (
|
|
1619
|
-
!ACCOUNT_GATED_NATIVE_OPENAI_MODELS.has(slug)
|
|
1618
|
+
!ACCOUNT_GATED_NATIVE_OPENAI_MODELS.has(slug)
|
|
1619
|
+
|| (accountId !== undefined
|
|
1620
|
+
&& codexModelEntitlementStateForAccount(modelEntitlements, accountId, slug) === "granted")
|
|
1620
1621
|
))] as const;
|
|
1621
1622
|
}))
|
|
1622
1623
|
: new Map<string, readonly string[]>();
|