@bman654/clodex 2.18.5 → 2.18.6

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/dist/cli.js CHANGED
@@ -74,7 +74,7 @@ import {
74
74
  withRegistryWriteLockSync,
75
75
  writeParentNoticeLines,
76
76
  writeParentNoticeLinesSync
77
- } from "./chunk-YGEPQOPA.js";
77
+ } from "./chunk-VFYRDLDD.js";
78
78
 
79
79
  // src/cli.ts
80
80
  import pc13 from "picocolors";
@@ -346,7 +346,7 @@ import { join } from "path";
346
346
  // package.json
347
347
  var package_default = {
348
348
  name: "@bman654/clodex",
349
- version: "2.18.5",
349
+ version: "2.18.6",
350
350
  publishConfig: {
351
351
  access: "public"
352
352
  },
@@ -6062,16 +6062,33 @@ function compareCodexClientVersions(a, b) {
6062
6062
  }
6063
6063
  return 0;
6064
6064
  }
6065
- function requiresNewerCodexClient(model) {
6066
- if (!model.useResponsesLite) return false;
6065
+ function atLeast(version, floor) {
6066
+ const order = compareCodexClientVersions(version, floor);
6067
+ return order === 0 || order === 1;
6068
+ }
6069
+ function codexClientRequirement(model) {
6070
+ if (!model.useResponsesLite) return void 0;
6067
6071
  const minimum = readCodexClientVersion(model.minimalClientVersion);
6068
- return minimum !== void 0 && compareCodexClientVersions(minimum, CODEX_RESPONSES_LITE_VERSION) === 1;
6072
+ const withheldAt = readCodexClientVersion(model.withheldAtClientVersion);
6073
+ const blockingMinimum = minimum !== void 0 && compareCodexClientVersions(minimum, CODEX_RESPONSES_LITE_VERSION) === 1 ? minimum : void 0;
6074
+ const blockingWithheld = withheldAt !== void 0 && atLeast(withheldAt, CODEX_RESPONSES_LITE_VERSION) ? withheldAt : void 0;
6075
+ if (blockingMinimum !== void 0 && (blockingWithheld === void 0 || compareCodexClientVersions(blockingMinimum, blockingWithheld) === 1)) {
6076
+ return { kind: "minimum", version: blockingMinimum };
6077
+ }
6078
+ return blockingWithheld === void 0 ? void 0 : { kind: "withheld", version: blockingWithheld };
6079
+ }
6080
+ function requiresNewerCodexClient(model) {
6081
+ return codexClientRequirement(model) !== void 0;
6069
6082
  }
6070
6083
  function codexClientVersionWarning(models) {
6071
- const unavailable = models.filter(requiresNewerCodexClient);
6084
+ const unavailable = models.flatMap((model) => {
6085
+ const requirement = codexClientRequirement(model);
6086
+ return requirement ? [{ id: model.id, requirement }] : [];
6087
+ });
6072
6088
  if (unavailable.length === 0) return void 0;
6073
- const details = unavailable.map((model) => `${printableServerText(model.id)} (requires ${model.minimalClientVersion})`).join(", ");
6074
- return `Hidden ChatGPT-plan models: ${details}. clodex sends Codex client version ${CODEX_RESPONSES_LITE_VERSION} for Responses-Lite; their catalog minimum exceeds this version. Update clodex to a release supporting their required version to use them.`;
6089
+ const details = unavailable.map(({ id, requirement }) => `${printableServerText(id)} (requires ${requirement.kind === "minimum" ? requirement.version : `a version newer than ${requirement.version}`})`).join(", ");
6090
+ const reason = unavailable.every(({ requirement }) => requirement.kind === "minimum") ? "their catalog minimum exceeds this version" : "the ChatGPT catalog does not offer them to this version";
6091
+ return `Hidden ChatGPT-plan models: ${details}. clodex sends Codex client version ${CODEX_RESPONSES_LITE_VERSION} for Responses-Lite; ${reason}. Update clodex to a release supporting their required version to use them.`;
6075
6092
  }
6076
6093
 
6077
6094
  // src/data/openai-oauth-models.ts
@@ -16629,12 +16646,7 @@ async function resolveRefreshCredentialWithSource(provider, resolveKey, selected
16629
16646
  return resolved;
16630
16647
  }
16631
16648
 
16632
- // src/registry/refresh-models.ts
16633
- async function refreshOAuthProvider(provider, accessToken) {
16634
- const tpl = provider.templateId ?? provider.id;
16635
- if (tpl === "openai" || tpl === "openai-oauth") return refreshOpenAiOAuthModels(accessToken);
16636
- throw new Error(`refreshOAuthProvider: unsupported template "${tpl}"`);
16637
- }
16649
+ // src/registry/openai-oauth-catalog.ts
16638
16650
  function positiveInteger2(value) {
16639
16651
  return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : void 0;
16640
16652
  }
@@ -16754,7 +16766,41 @@ async function fetchJsonWithAuth(url, accessToken, timeoutMs) {
16754
16766
  }
16755
16767
  }
16756
16768
  }
16757
- async function refreshOpenAiOAuthModels(accessToken) {
16769
+ async function markModelsWithheldAtRequestVersion(models, accessToken, timeoutMs, previous) {
16770
+ const pinned = await fetchJsonWithAuth(
16771
+ `https://chatgpt.com/backend-api/codex/models?client_version=${CODEX_RESPONSES_LITE_VERSION}`,
16772
+ accessToken,
16773
+ timeoutMs
16774
+ );
16775
+ const offered = readOfferedIds(pinned.body);
16776
+ if (!offered) return carryWithheldMarkers(models, previous);
16777
+ return models.map((model) => offered.has(model.id) ? model : { ...model, withheldAtClientVersion: CODEX_RESPONSES_LITE_VERSION });
16778
+ }
16779
+ function readOfferedIds(body) {
16780
+ if (!body || typeof body !== "object") return void 0;
16781
+ const record = body;
16782
+ const shape = Array.isArray(record.models) ? { rows: record.models, key: "slug" } : Array.isArray(record.data) ? { rows: record.data, key: "id" } : void 0;
16783
+ if (!shape || shape.rows.length === 0) return void 0;
16784
+ const ids = /* @__PURE__ */ new Set();
16785
+ for (const row of shape.rows) {
16786
+ const id = row !== null && typeof row === "object" ? row[shape.key] : void 0;
16787
+ if (typeof id !== "string" || id === "" || id !== id.trim()) return void 0;
16788
+ ids.add(id);
16789
+ }
16790
+ return ids;
16791
+ }
16792
+ function carryWithheldMarkers(models, previous) {
16793
+ const withheld = new Map(previous.flatMap((model) => {
16794
+ const version = readCodexClientVersion(model.withheldAtClientVersion);
16795
+ return version ? [[model.id, version]] : [];
16796
+ }));
16797
+ if (withheld.size === 0) return models;
16798
+ return models.map((model) => {
16799
+ const version = withheld.get(model.id);
16800
+ return version ? { ...model, withheldAtClientVersion: version } : model;
16801
+ });
16802
+ }
16803
+ async function refreshOpenAiOAuthModels(accessToken, previous = []) {
16758
16804
  const TIMEOUT_MS = 1e4;
16759
16805
  const seedById = new Map(buildOpenAiOAuthModels().map((m) => [m.id, m]));
16760
16806
  const toModels = (entries, codexCatalog) => entries.map((entry) => buildDynamicOAuthModel(entry, seedById, codexCatalog));
@@ -16766,7 +16812,11 @@ async function refreshOpenAiOAuthModels(accessToken) {
16766
16812
  );
16767
16813
  const codexEntries = parseOpenAiModelEntries(codexResult.body);
16768
16814
  if (codexEntries.length > 0) {
16769
- return { models: toModels(codexEntries, true), source: "live" };
16815
+ const models = toModels(codexEntries, true);
16816
+ return {
16817
+ models: await markModelsWithheldAtRequestVersion(models, accessToken, TIMEOUT_MS, previous),
16818
+ source: "live"
16819
+ };
16770
16820
  }
16771
16821
  const chatGptResult = await fetchJsonWithAuth(
16772
16822
  "https://chatgpt.com/backend-api/models",
@@ -16775,7 +16825,10 @@ async function refreshOpenAiOAuthModels(accessToken) {
16775
16825
  );
16776
16826
  const chatGptEntries = parseOpenAiModelEntries(chatGptResult.body).filter(({ id }) => !CHATGPT_CODEX_UNSUPPORTED_MODELS.has(id));
16777
16827
  if (chatGptEntries.length > 0) {
16778
- return { models: toModels(chatGptEntries, false), source: "live" };
16828
+ return {
16829
+ models: carryWithheldMarkers(toModels(chatGptEntries, false), previous),
16830
+ source: "live"
16831
+ };
16779
16832
  }
16780
16833
  const failures = [codexResult.error, chatGptResult.error].filter((error) => error !== void 0);
16781
16834
  const credentialFailure = failures.find((error) => /(?:\brejected\b|\b401\b|\b403\b)/i.test(error));
@@ -16786,6 +16839,15 @@ async function refreshOpenAiOAuthModels(accessToken) {
16786
16839
  credentialRejected: credentialFailure !== void 0
16787
16840
  };
16788
16841
  }
16842
+
16843
+ // src/registry/refresh-models.ts
16844
+ async function refreshOAuthProvider(provider, accessToken) {
16845
+ const tpl = provider.templateId ?? provider.id;
16846
+ if (tpl === "openai" || tpl === "openai-oauth") {
16847
+ return refreshOpenAiOAuthModels(accessToken, provider.modelsCache?.models);
16848
+ }
16849
+ throw new Error(`refreshOAuthProvider: unsupported template "${tpl}"`);
16850
+ }
16789
16851
  function warningSuffix(models) {
16790
16852
  const warning = codexClientVersionWarning(applyOAuthSeedContextMetadata(models));
16791
16853
  return warning ? ` ${warning}` : "";