dsh-codex-subscription 2.2.7 → 2.2.8

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.en.md CHANGED
@@ -32,6 +32,7 @@ Subscription access, model controls, quota management, and image creation in one
32
32
  | --- | --- | --- |
33
33
  | **Subscription sign-in** | Sign in to ChatGPT and use Codex subscription models without an API key | Normal chat needs no Codex CLI |
34
34
  | **Model catalog sync** | Read available models and reasoning levels from your account, with manual refresh; models marked for retirement show their retirement date next to the model name, without automatically switching your selection | New models appear when your account offers them |
35
+ | **Model list** | Show or hide individual models in the composer picker under Models & runtime | Display only; selected models and requests still work |
35
36
  | **Reasoning levels** | Choose supported reasoning effort in the composer | Levels vary by model |
36
37
  | **Fast mode** | Switch supported models between Standard and Fast, with a lightning indicator | Standard by default; Fast increases usage |
37
38
  | **Response verbosity** | Request short, medium, or detailed responses | Follows the model default unless changed |
package/README.md CHANGED
@@ -32,6 +32,7 @@
32
32
  | --- | --- | --- |
33
33
  | **订阅登录** | 直接登录 ChatGPT,使用 Codex 订阅模型,无需 API Key | 普通聊天无需 Codex CLI |
34
34
  | **模型目录同步** | 自动读取账号可用模型与推理档位,支持手动刷新;目录标注退役的模型会在模型名称旁显示退役日期,不会自动切换你的选择 | 新型号以账号目录开放情况为准 |
35
+ | **模型列表** | 在“模型与运行”中逐个显示或隐藏输入框中的模型 | 仅影响列表显示;已选模型和请求不受影响 |
35
36
  | **推理等级** | 在输入框选择模型支持的推理档位 | 档位随模型变化 |
36
37
  | **高速模式** | 在支持的模型上切换标准 / Fast,输入框显示闪电标识 | 默认标准;Fast 会增加用量消耗 |
37
38
  | **输出详略** | 选择简短、适中或详细的回答偏好 | 默认跟随模型 |
package/lib/client.js CHANGED
@@ -4930,6 +4930,8 @@ window.__ModuleLoader__.load({
4930
4930
  catalogRefresh: "刷新模型",
4931
4931
  catalogOnline: "已加载账户在线模型目录",
4932
4932
  catalogFallback: "当前使用内置模型目录;登录后可刷新账户可用模型",
4933
+ pickerModelsTitle: "输入框模型列表",
4934
+ pickerModelsHint: "只控制输入框中的模型列表;不会影响已选模型或模型请求。新模型默认显示。",
4933
4935
  searchMode: "订阅搜索模式",
4934
4936
  searchMode_live: "实时",
4935
4937
  searchMode_cached: "缓存(实验)",
@@ -5147,6 +5149,7 @@ window.__ModuleLoader__.load({
5147
5149
  selectModel: "选择模型",
5148
5150
  modelsLoading: "正在读取模型…",
5149
5151
  modelsEmpty: "没有可用模型。",
5152
+ modelsHidden: "所有模型都已从列表中隐藏;可在设置中重新显示。",
5150
5153
  effortsEmpty: "当前模型未提供推理等级。",
5151
5154
  modelRetry: "重试",
5152
5155
  modelDirectoryFailed: "模型目录加载失败,请重试。",
@@ -5478,6 +5481,8 @@ window.__ModuleLoader__.load({
5478
5481
  catalogRefresh: "Refresh models",
5479
5482
  catalogOnline: "Account model catalog loaded",
5480
5483
  catalogFallback: "Using the built-in catalog. Sign in to refresh account models.",
5484
+ pickerModelsTitle: "Models in picker",
5485
+ pickerModelsHint: "Only controls the composer model list. Selected models and requests still work. New models appear by default.",
5481
5486
  searchMode: "Subscription search mode",
5482
5487
  searchMode_live: "Live",
5483
5488
  searchMode_cached: "Cached (experimental)",
@@ -5695,6 +5700,7 @@ window.__ModuleLoader__.load({
5695
5700
  selectModel: "Select model",
5696
5701
  modelsLoading: "Loading models…",
5697
5702
  modelsEmpty: "No models available.",
5703
+ modelsHidden: "All models are hidden from this list. Show one in settings.",
5698
5704
  effortsEmpty: "This model provides no reasoning effort levels.",
5699
5705
  modelRetry: "Retry",
5700
5706
  modelDirectoryFailed: "Could not load the model directory. Try again.",
@@ -7021,6 +7027,7 @@ window.__ModuleLoader__.load({
7021
7027
  limitId: limit.id
7022
7028
  }))).filter((window) => Number.isFinite(window.remainingPercent) && window.remainingPercent >= 0 && window.remainingPercent <= (mode === "custom" ? readCapabilitySettings(thresholds)[window.windowSeconds > 0 && window.windowSeconds <= 6 * 3600 ? "quotaShortThreshold" : "quotaLongThreshold"] : mode === "early" && window.windowSeconds > 0 && window.windowSeconds <= 6 * 3600 ? 50 : 20) && (!Number.isFinite(window.resetsAt) || window.resetsAt * 1e3 > now)).sort((a, b) => a.remainingPercent - b.remainingPercent)[0];
7023
7029
  }
7030
+ const DISABLED_MODELS_FIELD = "disabledModels";
7024
7031
  const AUTO_QUOTA_RETRY_FIELD = "autoQuotaRetry";
7025
7032
  const QUICK_QUOTA_MODE_FIELD = "quickQuotaMode";
7026
7033
  const LEGACY_QUICK_QUOTA_FIELD = "quickQuotaVisible";
@@ -7086,6 +7093,7 @@ window.__ModuleLoader__.load({
7086
7093
  "gpt-6-astra": 272e3
7087
7094
  });
7088
7095
  const normalizeAutoQuotaRetry = (value) => typeof value === "boolean" ? value : false;
7096
+ const normalizeDisabledModels = (value) => Array.isArray(value) ? [...new Set(value.filter((id) => typeof id === "string" && /^[a-z][a-z0-9._-]{0,79}$/u.test(id)))].slice(0, 100) : [];
7089
7097
  const normalizeSearchProvider = (value) => [
7090
7098
  "auto",
7091
7099
  "dsh",
@@ -7136,6 +7144,7 @@ window.__ModuleLoader__.load({
7136
7144
  let failedPatch;
7137
7145
  let generation = 0;
7138
7146
  let contextModels = [];
7147
+ let availableModels = [];
7139
7148
  let verbosityModels = [];
7140
7149
  let fastModels;
7141
7150
  let catalogStatus;
@@ -7178,6 +7187,8 @@ window.__ModuleLoader__.load({
7178
7187
  ...Object.fromEntries(contextModels.map((model) => [model.key, clampModelContext(capabilities["customContextModels"][model.key] ?? value?.[CUSTOM_CONTEXT_MODEL_FIELDS[model.key]], model.maximum, model.default ?? CUSTOM_CONTEXT_MODEL_DEFAULTS[model.key])]))
7179
7188
  },
7180
7189
  contextModels,
7190
+ availableModels,
7191
+ disabledModels: normalizeDisabledModels(value?.[DISABLED_MODELS_FIELD]),
7181
7192
  verbosityModels,
7182
7193
  fastModels,
7183
7194
  catalogStatus,
@@ -7204,6 +7215,7 @@ window.__ModuleLoader__.load({
7204
7215
  subagentRuntimeInstalled = value?.subagentRuntimeInstalled === true;
7205
7216
  if (!modelRefreshStarted) {
7206
7217
  contextModels = Array.isArray(value?.contextModels) ? value.contextModels : [];
7218
+ availableModels = Array.isArray(value?.availableModels) ? value.availableModels : [];
7207
7219
  verbosityModels = Array.isArray(value?.verbosityModels) ? value.verbosityModels : [];
7208
7220
  fastModels = Array.isArray(value?.fastModels) ? value.fastModels : void 0;
7209
7221
  catalogStatus = value?.catalogStatus;
@@ -7212,6 +7224,7 @@ window.__ModuleLoader__.load({
7212
7224
  fallback = {
7213
7225
  status: "ready",
7214
7226
  value: {
7227
+ [DISABLED_MODELS_FIELD]: normalizeDisabledModels(value?.[DISABLED_MODELS_FIELD]),
7215
7228
  [AUTO_QUOTA_RETRY_FIELD]: normalizeAutoQuotaRetry(value?.[AUTO_QUOTA_RETRY_FIELD]),
7216
7229
  connectionMode: value?.connectionMode === "websocket" ? "websocket" : "sse",
7217
7230
  compactionMode: value?.compactionMode === "cloud" ? "cloud" : "dsh",
@@ -7246,6 +7259,7 @@ window.__ModuleLoader__.load({
7246
7259
  if (nativeSnapshot().status === "ready") {
7247
7260
  if (!modelRefreshStarted) {
7248
7261
  contextModels = Array.isArray(value?.contextModels) ? value.contextModels : [];
7262
+ availableModels = Array.isArray(value?.availableModels) ? value.availableModels : [];
7249
7263
  verbosityModels = Array.isArray(value?.verbosityModels) ? value.verbosityModels : [];
7250
7264
  fastModels = Array.isArray(value?.fastModels) ? value.fastModels : void 0;
7251
7265
  catalogStatus = value?.catalogStatus;
@@ -7268,12 +7282,14 @@ window.__ModuleLoader__.load({
7268
7282
  const value = unwrap(await rpc.call(CHANNEL, "preferences/models", {}));
7269
7283
  if (disposed || current !== modelRefreshGeneration) return false;
7270
7284
  const nextContextModels = Array.isArray(value?.contextModels) ? value.contextModels : [];
7285
+ const nextAvailableModels = Array.isArray(value?.availableModels) ? value.availableModels : [];
7271
7286
  const nextVerbosityModels = Array.isArray(value?.verbosityModels) ? value.verbosityModels : [];
7272
7287
  const nextFastModels = Array.isArray(value?.fastModels) ? value.fastModels : void 0;
7273
7288
  catalogStatus = value?.catalogStatus;
7274
- const changed = !sameModels(contextModels, nextContextModels) || !sameModels(verbosityModels, nextVerbosityModels) || JSON.stringify(fastModels) !== JSON.stringify(nextFastModels);
7289
+ const changed = !sameModels(contextModels, nextContextModels) || !sameModels(availableModels, nextAvailableModels) || !sameModels(verbosityModels, nextVerbosityModels) || JSON.stringify(fastModels) !== JSON.stringify(nextFastModels);
7275
7290
  if (changed) {
7276
7291
  contextModels = nextContextModels;
7292
+ availableModels = nextAvailableModels;
7277
7293
  verbosityModels = nextVerbosityModels;
7278
7294
  fastModels = nextFastModels;
7279
7295
  publish();
@@ -7636,7 +7652,7 @@ window.__ModuleLoader__.load({
7636
7652
  }
7637
7653
  //#endregion
7638
7654
  //#region src/version.js
7639
- const PACKAGE_VERSION = "2.2.7";
7655
+ const PACKAGE_VERSION = "2.2.8";
7640
7656
  //#endregion
7641
7657
  //#region src/client-recovery.js
7642
7658
  async function recoveryCall(rpc, endpoint, payload = {}, timeoutMs = 1e4) {
@@ -7901,6 +7917,13 @@ window.__ModuleLoader__.load({
7901
7917
  ...model.reasoning?.defaultEffort === void 0 ? {} : { reasoningEffort: model.reasoning.defaultEffort }
7902
7918
  }
7903
7919
  }))), [state.groups]);
7920
+ const visibleGroups = (0, react.useMemo)(() => {
7921
+ const hidden = new Set(preferenceSnapshot.disabledModels);
7922
+ return state.groups.map((group) => group.id === "openai-codex" ? {
7923
+ ...group,
7924
+ models: group.models.filter((model) => !hidden.has(model.id))
7925
+ } : group).filter((group) => group.models.length > 0);
7926
+ }, [state.groups, preferenceSnapshot.disabledModels]);
7904
7927
  const currentChoice = choices.find((choice) => choice.selection.provider === state.current?.provider && choice.selection.model === state.current?.model);
7905
7928
  const reasoning = currentChoice?.model.reasoning;
7906
7929
  const effectiveEffort = state.current?.reasoningEffort ?? reasoning?.defaultEffort;
@@ -8072,7 +8095,7 @@ window.__ModuleLoader__.load({
8072
8095
  }, failure.id)),
8073
8096
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8074
8097
  className: "codexModelSelectGroups scrollable",
8075
- children: state.groups.map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
8098
+ children: visibleGroups.map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
8076
8099
  className: "codexModelSelectGroup",
8077
8100
  role: "group",
8078
8101
  "aria-labelledby": `${id}-${group.id}`,
@@ -8093,9 +8116,9 @@ window.__ModuleLoader__.load({
8093
8116
  }))]
8094
8117
  }, group.id))
8095
8118
  }),
8096
- state.status === "ready" && choices.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8119
+ state.status === "ready" && visibleGroups.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8097
8120
  className: "codexModelSelectEmpty",
8098
- children: t("modelsEmpty")
8121
+ children: t(choices.length === 0 ? "modelsEmpty" : "modelsHidden")
8099
8122
  }) : null
8100
8123
  ]
8101
8124
  });
@@ -8875,6 +8898,49 @@ window.__ModuleLoader__.load({
8875
8898
  })]
8876
8899
  });
8877
8900
  }
8901
+ /** Show every account model while saving which entries the composer picker hides. */
8902
+ function PickerModelsPreference({ preference, t }) {
8903
+ const snapshot = usePreferenceSnapshot(preference);
8904
+ const writable = snapshot.status === "ready" && snapshot.writable === true;
8905
+ const hidden = snapshot.disabledModels;
8906
+ const toggle = (modelId) => {
8907
+ const next = hidden.includes(modelId) ? hidden.filter((id) => id !== modelId) : [...hidden, modelId];
8908
+ preference.set({ [DISABLED_MODELS_FIELD]: next });
8909
+ };
8910
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8911
+ className: "codexSubscriptionContext",
8912
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8913
+ className: "codexSubscriptionContextCopy",
8914
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8915
+ className: "codexSubscriptionPreferenceLabel",
8916
+ children: t("pickerModelsTitle")
8917
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8918
+ className: "codexSubscriptionContextHint",
8919
+ children: t("pickerModelsHint")
8920
+ })]
8921
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8922
+ className: "codexSubscriptionContextModels",
8923
+ role: "group",
8924
+ "aria-label": t("pickerModelsTitle"),
8925
+ children: snapshot.availableModels.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8926
+ className: "codexSubscriptionContextModel",
8927
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8928
+ className: "codexSubscriptionContextModelCopy",
8929
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: model.name })
8930
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8931
+ className: "codexSubscriptionSwitch",
8932
+ type: "button",
8933
+ role: "switch",
8934
+ "aria-label": model.name,
8935
+ "aria-checked": !hidden.includes(model.id),
8936
+ disabled: !writable,
8937
+ onClick: () => toggle(model.id),
8938
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "codexSubscriptionSwitchKnob" })
8939
+ })]
8940
+ }, model.id))
8941
+ })]
8942
+ });
8943
+ }
8878
8944
  function ContextWindowPreference({ preference, t }) {
8879
8945
  const snapshot = usePreferenceSnapshot(preference);
8880
8946
  const writable = snapshot.status === "ready" && snapshot.writable === true;
@@ -9050,6 +9116,11 @@ window.__ModuleLoader__.load({
9050
9116
  t
9051
9117
  }),
9052
9118
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
9119
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PickerModelsPreference, {
9120
+ preference,
9121
+ t
9122
+ }),
9123
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
9053
9124
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ContextWindowPreference, {
9054
9125
  preference,
9055
9126
  t
package/lib/index.js CHANGED
@@ -193,6 +193,7 @@ function capabilityPatch(payload) {
193
193
  //#endregion
194
194
  //#region src/settings-contract.js
195
195
  const SETTINGS_NAMESPACE = "codex-subscription";
196
+ const DISABLED_MODELS_FIELD = "disabledModels";
196
197
  const AUTO_QUOTA_RETRY_FIELD = "autoQuotaRetry";
197
198
  const QUICK_QUOTA_MODE_FIELD = "quickQuotaMode";
198
199
  const LEGACY_QUICK_QUOTA_FIELD = "quickQuotaVisible";
@@ -258,6 +259,7 @@ const CUSTOM_CONTEXT_MODEL_DEFAULTS = Object.freeze({
258
259
  "gpt-6-astra": 272e3
259
260
  });
260
261
  const normalizeAutoQuotaRetry = (value) => typeof value === "boolean" ? value : false;
262
+ const normalizeDisabledModels = (value) => Array.isArray(value) ? [...new Set(value.filter((id) => typeof id === "string" && /^[a-z][a-z0-9._-]{0,79}$/u.test(id)))].slice(0, 100) : [];
261
263
  const normalizeOutputVerbosity = (value) => [
262
264
  "default",
263
265
  "low",
@@ -3044,7 +3046,7 @@ async function readSubscriptionCredentials(getAuth, readCredential, signal) {
3044
3046
  }
3045
3047
  //#endregion
3046
3048
  //#region src/version.js
3047
- const PACKAGE_VERSION = "2.2.7";
3049
+ const PACKAGE_VERSION = "2.2.8";
3048
3050
  const USER_AGENT = `dsh-codex-subscription/${PACKAGE_VERSION}`;
3049
3051
  //#endregion
3050
3052
  //#region src/model-catalog.js
@@ -5821,6 +5823,7 @@ function createSubscriptionRpcHandler({ authHandler, usageReader, resetCreditSer
5821
5823
  return {
5822
5824
  ok: true,
5823
5825
  value: {
5826
+ availableModels: Array.isArray(value?.availableModels) ? value.availableModels : [],
5824
5827
  contextModels: Array.isArray(value?.contextModels) ? value.contextModels : [],
5825
5828
  verbosityModels: Array.isArray(value?.verbosityModels) ? value.verbosityModels : [],
5826
5829
  fastModels: Array.isArray(value?.fastModels) ? value.fastModels : [],
@@ -5835,6 +5838,11 @@ function createSubscriptionRpcHandler({ authHandler, usageReader, resetCreditSer
5835
5838
  signal.throwIfAborted();
5836
5839
  if (endpoint === "preferences/update") {
5837
5840
  const patch = capabilityPatch(payload);
5841
+ if (Object.hasOwn(payload ?? {}, "disabledModels")) {
5842
+ const disabled = payload[DISABLED_MODELS_FIELD];
5843
+ if (!Array.isArray(disabled) || disabled.length > 100 || disabled.length !== normalizeDisabledModels(disabled).length) return publicError("internal", "Invalid disabled models preference");
5844
+ patch[DISABLED_MODELS_FIELD] = disabled;
5845
+ }
5838
5846
  if (Object.hasOwn(payload ?? {}, "autoQuotaRetry")) {
5839
5847
  if (typeof payload["autoQuotaRetry"] !== "boolean") return publicError("internal", "Invalid automatic quota retry preference");
5840
5848
  patch[AUTO_QUOTA_RETRY_FIELD] = payload[AUTO_QUOTA_RETRY_FIELD];
@@ -5976,6 +5984,7 @@ function createSearchProviderSwitcher(loader) {
5976
5984
  });
5977
5985
  }
5978
5986
  const settingsFields = {
5987
+ [DISABLED_MODELS_FIELD]: z.transform(z.array(z.string()).max(100), normalizeDisabledModels).default([]),
5979
5988
  [AUTO_QUOTA_RETRY_FIELD]: z.boolean().default(false),
5980
5989
  ...Object.fromEntries(Object.entries(PREFERENCE_FIELDS).map(([field, rule]) => [field, rule.default === void 0 ? z.union(rule.choices) : z.union(rule.choices).default(rule.default)])),
5981
5990
  imageModel: z.union(Object.keys(IMAGE_MODELS)).default(DEFAULT_IMAGE_MODEL),
@@ -6062,29 +6071,37 @@ function apply(ctx, config = {}) {
6062
6071
  runNetwork: network.run
6063
6072
  });
6064
6073
  const preferences = {
6065
- status: () => ({
6066
- [AUTO_QUOTA_RETRY_FIELD]: normalizeAutoQuotaRetry(settings.get()[AUTO_QUOTA_RETRY_FIELD]),
6067
- compactionMode: settings.get().compactionMode ?? "dsh",
6068
- connectionMode: settings.get().connectionMode ?? "sse",
6069
- subagentBackend: settings.get().subagentBackend ?? "dsh",
6070
- subagentBackendAvailable: subagentBackend !== void 0,
6071
- subagentRuntimeInstalled: inspectSubagentRuntime().installed,
6072
- ...readCapabilitySettings(settings.get()),
6073
- [QUICK_QUOTA_MODE_FIELD]: normalizeQuickQuotaMode(settings.get()[QUICK_QUOTA_MODE_FIELD], settings.get()[LEGACY_QUICK_QUOTA_FIELD]),
6074
- [SEARCH_PROVIDER_FIELD]: settings.get()[SEARCH_PROVIDER_FIELD],
6075
- [SPEED_MODE_FIELD]: settings.get()[SPEED_MODE_FIELD],
6076
- [OUTPUT_VERBOSITY_FIELD]: normalizeOutputVerbosity(settings.get()[OUTPUT_VERBOSITY_FIELD]),
6077
- [INPUT_IMAGE_DETAIL_FIELD]: normalizeInputImageDetail(settings.get()[INPUT_IMAGE_DETAIL_FIELD]),
6078
- [STREAM_IDLE_TIMEOUT_MINUTES_FIELD]: normalizeStreamIdleTimeoutMinutes(settings.get()[STREAM_IDLE_TIMEOUT_MINUTES_FIELD]),
6079
- [CONTEXT_MODE_FIELD]: normalizeContextMode(settings.get()[CONTEXT_MODE_FIELD]),
6080
- [CUSTOM_CONTEXT_WINDOW_FIELD]: normalizeCustomContextWindow(settings.get()[CUSTOM_CONTEXT_WINDOW_FIELD]),
6081
- ...Object.fromEntries(Object.entries(CUSTOM_CONTEXT_MODEL_FIELDS).map(([modelKey, field]) => [field, normalizeCustomContextWindow(settings.get()[field] ?? CUSTOM_CONTEXT_MODEL_DEFAULTS[modelKey], CUSTOM_CONTEXT_MODEL_CAPS[modelKey])])),
6082
- contextModels: contextModelGroups(modelCatalog.getModels(baseProvider.getModels())),
6083
- catalogStatus: modelCatalog.status(),
6084
- verbosityModels: provider.getModels().filter((model) => modelCatalog.metadata(model.id)?.supportVerbosity ?? model.id !== "gpt-5.3-codex-spark").map((model) => model.id),
6085
- fastModels: provider.getModels().filter((model) => modelCatalog.metadata(model.id)?.supportsFast ?? supportsCodexFastMode(model.id)).map((model) => model.id),
6086
- writable: ctx.settings.writable
6087
- }),
6074
+ status: () => {
6075
+ const models = modelCatalog.getModels(baseProvider.getModels());
6076
+ return {
6077
+ [DISABLED_MODELS_FIELD]: normalizeDisabledModels(settings.get()[DISABLED_MODELS_FIELD]),
6078
+ [AUTO_QUOTA_RETRY_FIELD]: normalizeAutoQuotaRetry(settings.get()[AUTO_QUOTA_RETRY_FIELD]),
6079
+ compactionMode: settings.get().compactionMode ?? "dsh",
6080
+ connectionMode: settings.get().connectionMode ?? "sse",
6081
+ subagentBackend: settings.get().subagentBackend ?? "dsh",
6082
+ subagentBackendAvailable: subagentBackend !== void 0,
6083
+ subagentRuntimeInstalled: inspectSubagentRuntime().installed,
6084
+ ...readCapabilitySettings(settings.get()),
6085
+ [QUICK_QUOTA_MODE_FIELD]: normalizeQuickQuotaMode(settings.get()[QUICK_QUOTA_MODE_FIELD], settings.get()[LEGACY_QUICK_QUOTA_FIELD]),
6086
+ [SEARCH_PROVIDER_FIELD]: settings.get()[SEARCH_PROVIDER_FIELD],
6087
+ [SPEED_MODE_FIELD]: settings.get()[SPEED_MODE_FIELD],
6088
+ [OUTPUT_VERBOSITY_FIELD]: normalizeOutputVerbosity(settings.get()[OUTPUT_VERBOSITY_FIELD]),
6089
+ [INPUT_IMAGE_DETAIL_FIELD]: normalizeInputImageDetail(settings.get()[INPUT_IMAGE_DETAIL_FIELD]),
6090
+ [STREAM_IDLE_TIMEOUT_MINUTES_FIELD]: normalizeStreamIdleTimeoutMinutes(settings.get()[STREAM_IDLE_TIMEOUT_MINUTES_FIELD]),
6091
+ [CONTEXT_MODE_FIELD]: normalizeContextMode(settings.get()[CONTEXT_MODE_FIELD]),
6092
+ [CUSTOM_CONTEXT_WINDOW_FIELD]: normalizeCustomContextWindow(settings.get()[CUSTOM_CONTEXT_WINDOW_FIELD]),
6093
+ ...Object.fromEntries(Object.entries(CUSTOM_CONTEXT_MODEL_FIELDS).map(([modelKey, field]) => [field, normalizeCustomContextWindow(settings.get()[field] ?? CUSTOM_CONTEXT_MODEL_DEFAULTS[modelKey], CUSTOM_CONTEXT_MODEL_CAPS[modelKey])])),
6094
+ contextModels: contextModelGroups(models),
6095
+ availableModels: models.map(({ id, name }) => ({
6096
+ id,
6097
+ name
6098
+ })),
6099
+ catalogStatus: modelCatalog.status(),
6100
+ verbosityModels: provider.getModels().filter((model) => modelCatalog.metadata(model.id)?.supportVerbosity ?? model.id !== "gpt-5.3-codex-spark").map((model) => model.id),
6101
+ fastModels: provider.getModels().filter((model) => modelCatalog.metadata(model.id)?.supportsFast ?? supportsCodexFastMode(model.id)).map((model) => model.id),
6102
+ writable: ctx.settings.writable
6103
+ };
6104
+ },
6088
6105
  update: async (patch) => {
6089
6106
  if (Object.hasOwn(patch, "subagentBackend")) {
6090
6107
  if (!subagentBackend) throw new Error("DSH subagent services are unavailable");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-codex-subscription",
3
- "version": "2.2.7",
3
+ "version": "2.2.8",
4
4
  "description": "Use ChatGPT and Codex subscriptions in DeepSeek Harness with OAuth, quota, safe resets, web search, images, and Fast mode",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",