dsh-codex-subscription 2.2.11 → 2.4.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/lib/index.js CHANGED
@@ -206,6 +206,7 @@ const DEFAULT_SEARCH_PROVIDER = SEARCH_PROVIDER_AUTO;
206
206
  const SPEED_MODE_FIELD = "speedMode";
207
207
  const SPEED_MODE_STANDARD = "standard";
208
208
  const SPEED_MODE_FAST = "fast";
209
+ const SPEED_MODE_ULTRAFAST = "ultrafast";
209
210
  const DEFAULT_SPEED_MODE = SPEED_MODE_STANDARD;
210
211
  const OUTPUT_VERBOSITY_FIELD = "outputVerbosity";
211
212
  const OUTPUT_VERBOSITY_DEFAULT = "default";
@@ -364,7 +365,11 @@ const PREFERENCE_FIELDS = Object.freeze({
364
365
  error: "Invalid search provider preference"
365
366
  },
366
367
  [SPEED_MODE_FIELD]: {
367
- choices: [SPEED_MODE_STANDARD, SPEED_MODE_FAST],
368
+ choices: [
369
+ SPEED_MODE_STANDARD,
370
+ SPEED_MODE_FAST,
371
+ SPEED_MODE_ULTRAFAST
372
+ ],
368
373
  default: DEFAULT_SPEED_MODE,
369
374
  error: "Invalid speed mode preference"
370
375
  },
@@ -1200,13 +1205,18 @@ const SUPPORTED_RUNTIME_VERSIONS = Object.freeze([
1200
1205
  ]);
1201
1206
  const require = createRequire(import.meta.url);
1202
1207
  const execute = promisify(execFile);
1208
+ /** The DSH release this plugin is loaded into, read from the host's own LLM package. */
1209
+ function hostDshVersion(resolve = require.resolve, entry = process.argv[1]) {
1210
+ const attempts = [() => resolve("@deepseek-ai/dsh-llm/package.json")];
1211
+ if (typeof entry === "string" && entry) attempts.push(() => require.resolve("@deepseek-ai/dsh-llm/package.json", { paths: [dirname(entry)] }));
1212
+ for (const attempt of attempts) try {
1213
+ const { version } = JSON.parse(readFileSync(attempt(), "utf8"));
1214
+ if (typeof version === "string" && /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u.test(version)) return version;
1215
+ } catch {}
1216
+ }
1203
1217
  function matchingSubagentRuntimeVersion(resolve = require.resolve) {
1204
- try {
1205
- const host = JSON.parse(readFileSync(resolve("@deepseek-ai/dsh-llm/package.json"), "utf8"));
1206
- return SUPPORTED_RUNTIME_VERSIONS.includes(host.version) ? host.version : void 0;
1207
- } catch {
1208
- return;
1209
- }
1218
+ const version = hostDshVersion(resolve, resolve === require.resolve ? process.argv[1] : "");
1219
+ return SUPPORTED_RUNTIME_VERSIONS.includes(version) ? version : void 0;
1210
1220
  }
1211
1221
  function inspectSubagentRuntime(resolve = require.resolve) {
1212
1222
  try {
@@ -1794,7 +1804,8 @@ const sketchCommandArray = {
1794
1804
  "stroke",
1795
1805
  "object",
1796
1806
  "layer",
1797
- "resize"
1807
+ "resize",
1808
+ "svg"
1798
1809
  ]
1799
1810
  },
1800
1811
  id: {
@@ -1858,6 +1869,10 @@ const sketchCommandArray = {
1858
1869
  "clear"
1859
1870
  ]
1860
1871
  },
1872
+ svg: {
1873
+ type: "string",
1874
+ description: "op svg only: a complete <svg viewBox=\"0 0 W H\"> document (W and H equal to the canvas width and height from inspect). Imported as native editable strokes; the fastest way to draw a whole scene. Optional layer sets the target layer."
1875
+ },
1861
1876
  value: string,
1862
1877
  ratio: {
1863
1878
  type: "string",
@@ -1883,7 +1898,7 @@ const sketchCommandArray = {
1883
1898
  function createSketchAgentTool(bridge, attachments) {
1884
1899
  return defineTool({
1885
1900
  name: "codex_sketch",
1886
- description: "Edit the sketch board in this session using native editable strokes and layers. Use for @sketch requests and explicit follow-up edits to that drawing. The toolbar pen button is for manual drawing; do not require the user to open it. Start with inspect for the runId, documentId, revision and command reference. Apply atomic batches, preview between stages, and call finish to save the finished draft and release the editing lock. save is only a checkpoint. finish returns an image only when the user enables experimental preview feedback. Closing the board does not stop drawing. If the user stops drawing, do not retry. Never generates AI images, sends messages or attaches images automatically. Inspect automatically opens the board in the currently viewed session. Do not ask the user to open it first. If the session is not visible in DSH, ask them to switch to it. On timeout inspect before retrying; reuse the exact requestId only for the same request.",
1901
+ description: "Edit the sketch board in this session using native editable strokes and layers. Use for @sketch requests and explicit follow-up edits to that drawing. The toolbar pen button is for manual drawing; do not require the user to open it. Start with inspect for the runId, documentId, revision and command reference. Draw with the svg op whenever possible: one SVG document per stage (paths, shapes, groups, transforms; see the reference from inspect) is far faster and richer than hand-placed strokes, and still becomes native editable strokes. Use stroke commands for small edits and native text. Apply atomic batches, preview between stages, and call finish to save the finished draft and release the editing lock. save is only a checkpoint. finish returns an image only when the user enables experimental preview feedback. Closing the board does not stop drawing. If the user stops drawing, do not retry. Never generates AI images, sends messages or attaches images automatically. Inspect automatically opens the board in the currently viewed session. Do not ask the user to open it first. If the session is not visible in DSH, ask them to switch to it. On timeout inspect before retrying; reuse the exact requestId only for the same request.",
1887
1902
  parameters: {
1888
1903
  action: {
1889
1904
  type: "string",
@@ -2878,6 +2893,7 @@ function normalizeTransportEvent(event, signal) {
2878
2893
  //#endregion
2879
2894
  //#region src/pi-ai-runtime.js
2880
2895
  const FAST_SERVICE_TIER = "priority";
2896
+ const ULTRAFAST_SERVICE_TIER = "ultrafast";
2881
2897
  /** Apply the chosen detail to user and tool-result images after the provider assembles the request. */
2882
2898
  function withInputImageDetail(payload, detail) {
2883
2899
  if (!Array.isArray(payload.input)) return payload;
@@ -2937,13 +2953,14 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
2937
2953
  const metadata = modelMetadata(model);
2938
2954
  const requestedVerbosity = resolveOutputVerbosity();
2939
2955
  const textVerbosity = supportsVerbosity(model) ? requestedVerbosity === "default" ? metadata?.defaultVerbosity ?? "medium" : requestedVerbosity : void 0;
2940
- const fast = resolveSpeedMode() === "fast" && (metadata?.supportsFast ?? supportsCodexFastMode(model?.id));
2956
+ const speedMode = resolveSpeedMode();
2957
+ const serviceTier = speedMode === "ultrafast" && metadata?.supportsUltrafast === true ? ULTRAFAST_SERVICE_TIER : speedMode === "fast" && (metadata?.supportsFast ?? supportsCodexFastMode(model?.id)) ? FAST_SERVICE_TIER : void 0;
2941
2958
  const inputImageDetail = normalizeInputImageDetail(resolveInputImageDetail());
2942
2959
  const onPayload = options.onPayload;
2943
2960
  return {
2944
2961
  ...options,
2945
2962
  ...textVerbosity === void 0 ? {} : { textVerbosity },
2946
- ...fast ? { serviceTier: FAST_SERVICE_TIER } : {},
2963
+ ...serviceTier === void 0 ? {} : { serviceTier },
2947
2964
  async onPayload(payload, requestModel) {
2948
2965
  const preferred = {
2949
2966
  ...payload,
@@ -2951,7 +2968,7 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
2951
2968
  ...payload.text ?? {},
2952
2969
  verbosity: textVerbosity
2953
2970
  } },
2954
- ...fast ? { service_tier: FAST_SERVICE_TIER } : {}
2971
+ ...serviceTier === void 0 ? {} : { service_tier: serviceTier }
2955
2972
  };
2956
2973
  const managed = compaction?.preparePayload(preferred, model?.contextWindow) ?? preferred;
2957
2974
  const next = await onPayload?.(managed, requestModel);
@@ -2962,7 +2979,7 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
2962
2979
  ...detailed.text ?? {},
2963
2980
  verbosity: textVerbosity
2964
2981
  } },
2965
- ...fast ? { service_tier: FAST_SERVICE_TIER } : {}
2982
+ ...serviceTier === void 0 ? {} : { service_tier: serviceTier }
2966
2983
  };
2967
2984
  }
2968
2985
  };
@@ -3051,7 +3068,7 @@ async function readSubscriptionCredentials(getAuth, readCredential, signal) {
3051
3068
  }
3052
3069
  //#endregion
3053
3070
  //#region src/version.js
3054
- const PACKAGE_VERSION = "2.2.11";
3071
+ const PACKAGE_VERSION = "2.4.0";
3055
3072
  const USER_AGENT = `dsh-codex-subscription/${PACKAGE_VERSION}`;
3056
3073
  //#endregion
3057
3074
  //#region src/model-catalog.js
@@ -3114,6 +3131,7 @@ function reasoningMap(levels) {
3114
3131
  return map;
3115
3132
  }
3116
3133
  const capabilityNames = (values) => [...new Set(values.filter((value) => typeof value === "string" && /^[a-z][a-z0-9_-]{0,31}$/u.test(value)))].sort().slice(0, 16);
3134
+ const speedTierIds = (value) => [...Array.isArray(value.additional_speed_tiers) ? value.additional_speed_tiers : [], ...Array.isArray(value.service_tiers) ? value.service_tiers.map((tier) => tier?.id) : []];
3117
3135
  function unsupportedCapabilities(value) {
3118
3136
  const reasoning = capabilityNames((value.supported_reasoning_levels ?? []).map((item) => item?.effort)).filter((level) => !["none", ...LEVELS.slice(1)].includes(level));
3119
3137
  const inputs = capabilityNames(Array.isArray(value.input_modalities) ? value.input_modalities : []).filter((input) => !["text", "image"].includes(input));
@@ -3122,7 +3140,8 @@ function unsupportedCapabilities(value) {
3122
3140
  "default",
3123
3141
  "standard",
3124
3142
  "fast",
3125
- "priority"
3143
+ "priority",
3144
+ "ultrafast"
3126
3145
  ].includes(tier));
3127
3146
  return {
3128
3147
  ...reasoning.length ? { reasoning } : {},
@@ -3166,7 +3185,8 @@ function visibleModel(value, displayNames, now) {
3166
3185
  "medium",
3167
3186
  "high"
3168
3187
  ].includes(value.default_verbosity) ? value.default_verbosity : void 0,
3169
- supportsFast: [...Array.isArray(value.additional_speed_tiers) ? value.additional_speed_tiers : [], ...Array.isArray(value.service_tiers) ? value.service_tiers.map((tier) => tier?.id) : []].some((tier) => tier === "fast" || tier === "priority")
3188
+ supportsFast: speedTierIds(value).some((tier) => tier === "fast" || tier === "priority"),
3189
+ supportsUltrafast: speedTierIds(value).includes("ultrafast")
3170
3190
  };
3171
3191
  }
3172
3192
  function parseOfficialModelCatalog(value, now = Date.now()) {
@@ -3541,6 +3561,23 @@ const PATH_LIKE_ATTACHMENT_ID = /[\\/]/u;
3541
3561
  const FILE_NAME_ATTACHMENT_ID = /\.[A-Za-z0-9]{1,16}$/u;
3542
3562
  const record$2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
3543
3563
  const nonEmpty = (value) => typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
3564
+ const NETWORK_REASONS = {
3565
+ UND_ERR_HEADERS_TIMEOUT: "the image service sent no response within 5 minutes",
3566
+ UND_ERR_BODY_TIMEOUT: "the image response stalled",
3567
+ UND_ERR_CONNECT_TIMEOUT: "the connection to the image service timed out",
3568
+ UND_ERR_SOCKET: "the connection closed unexpectedly",
3569
+ ECONNRESET: "the connection was reset",
3570
+ ETIMEDOUT: "the connection timed out",
3571
+ ENOTFOUND: "DNS lookup failed",
3572
+ ECONNREFUSED: "the connection was refused",
3573
+ EAI_AGAIN: "DNS lookup failed"
3574
+ };
3575
+ function requestFailureReason(error) {
3576
+ const code = [(error?.cause ?? error)?.code, error?.code].find((value) => typeof value === "string" && /^[A-Z][A-Z0-9_]{2,39}$/u.test(value));
3577
+ if (code !== void 0) return `: ${NETWORK_REASONS[code] ?? "network error"} (${code})`;
3578
+ if (error?.name === "TimeoutError") return ": the image request timed out";
3579
+ return "";
3580
+ }
3544
3581
  function normalizeImageOptions(args) {
3545
3582
  const quality = nonEmpty(args?.quality) ?? "auto";
3546
3583
  const background = nonEmpty(args?.background) ?? "auto";
@@ -3945,7 +3982,7 @@ function createCodexImageTool(options) {
3945
3982
  });
3946
3983
  } catch (error) {
3947
3984
  if (exec.signal.aborted) throw exec.signal.reason;
3948
- throw new Error(`Codex image ${editing ? "edit" : "generation"} request failed`, { cause: error });
3985
+ throw new Error(`Codex image ${editing ? "edit" : "generation"} request failed${requestFailureReason(error)}`, { cause: error });
3949
3986
  }
3950
3987
  if (!response.ok) {
3951
3988
  if (response.status === 401 || response.status === 403) throw new Error("ChatGPT sign-in needs to be renewed");
@@ -4632,7 +4669,8 @@ async function createSubscriptionDiagnostics({ auth, preferences, login = { phas
4632
4669
  runtime: {
4633
4670
  node: process.version,
4634
4671
  platform: process.platform,
4635
- arch: process.arch
4672
+ arch: process.arch,
4673
+ ...hostDshVersion() ? { dsh: hostDshVersion() } : {}
4636
4674
  },
4637
4675
  account,
4638
4676
  login,
@@ -5829,6 +5867,7 @@ function createSubscriptionRpcHandler({ authHandler, usageReader, resetCreditSer
5829
5867
  contextModels: Array.isArray(value?.contextModels) ? value.contextModels : [],
5830
5868
  verbosityModels: Array.isArray(value?.verbosityModels) ? value.verbosityModels : [],
5831
5869
  fastModels: Array.isArray(value?.fastModels) ? value.fastModels : [],
5870
+ ultrafastModels: Array.isArray(value?.ultrafastModels) ? value.ultrafastModels : [],
5832
5871
  catalogStatus: value?.catalogStatus
5833
5872
  }
5834
5873
  };
@@ -6100,6 +6139,7 @@ function apply(ctx, config = {}) {
6100
6139
  })),
6101
6140
  catalogStatus: modelCatalog.status(),
6102
6141
  verbosityModels: provider.getModels().filter((model) => modelCatalog.metadata(model.id)?.supportVerbosity ?? model.id !== "gpt-5.3-codex-spark").map((model) => model.id),
6142
+ ultrafastModels: provider.getModels().filter((model) => modelCatalog.metadata(model.id)?.supportsUltrafast === true).map((model) => model.id),
6103
6143
  fastModels: provider.getModels().filter((model) => modelCatalog.metadata(model.id)?.supportsFast ?? supportsCodexFastMode(model.id)).map((model) => model.id),
6104
6144
  writable: ctx.settings.writable
6105
6145
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-codex-subscription",
3
- "version": "2.2.11",
3
+ "version": "2.4.0",
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",