dsh-codex-subscription 2.1.1-beta.2 → 2.1.2

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
@@ -249,7 +249,7 @@ see the [OpenAI Codex Speed documentation](https://learn.chatgpt.com/docs/agent-
249
249
  Opt in under **Advanced & diagnostics**. SSE and DSH subtasks remain the defaults:
250
250
 
251
251
  - **WebSocket** reuses connections and eligible context transfers. Failed handshakes can fall back to SSE; interrupted responses surface an error without automatic replay. Applies to the next request, does not expand context limits, and is not guaranteed to be faster.
252
- - **Codex independent subtasks** reuse your subscription login and the official DSH Codex runtime, without a separate login or CLI setup. They follow the current subscription model and workspace permissions; other model sessions use Luna low. Shared-context subtasks remain with DSH.
252
+ - **Codex independent subtasks** reuse your subscription login and the official DSH Codex runtime, without a separate login or CLI setup. They inherit the current subscription model and workspace permissions by default. Enable DSH subtask model selection, configure allowed models and start a new session to specify the child model and reasoning effort in chat. Non-subscription sessions must explicitly select a subscription model. Shared-context subtasks remain with DSH.
253
253
 
254
254
  ## Update and uninstall
255
255
 
package/README.md CHANGED
@@ -248,7 +248,7 @@ ChatGPT 返回可用重置卡时,设置页会把每张卡分别显示为紧凑
248
248
  在 **高级与诊断** 中按需开启,默认仍使用 SSE 和 DSH 子任务:
249
249
 
250
250
  - **WebSocket**:复用连接和可复用的上下文传输;握手失败可回退 SSE,已开始的响应中断会报错,不自动重放。下次请求生效,不增加模型上下文容量,也不保证更快。
251
- - **Codex 独立子任务**:复用订阅登录和官方 DSH Codex 运行时,无需另行登录或配置 CLI。跟随当前订阅模型及工作区权限;其他模型会话使用 Luna low。共享上下文的子任务仍交给 DSH。
251
+ - **Codex 独立子任务**:复用订阅登录和官方 DSH Codex 运行时,无需另行登录或配置 CLI。默认继承当前订阅模型及工作区权限。开启 DSH 子任务模型选择、配置允许模型并新建会话后,可在聊天中指定子任务模型与推理档位;非订阅会话需明确选择订阅模型。共享上下文的子任务仍交给 DSH。
252
252
 
253
253
  ## 更新与卸载
254
254
 
package/lib/client.js CHANGED
@@ -4472,7 +4472,7 @@ window.__ModuleLoader__.load({
4472
4472
  subagentBackend_codex: "Codex",
4473
4473
  connectionTitle: "连接方式",
4474
4474
  connectionHint: "默认 SSE。WebSocket 实验性复用连接与上下文传输;连接失败可回退 SSE。下次请求生效,不扩大上下文容量。",
4475
- subagentBackendHint: "Codex 复用订阅登录,跟随当前订阅模型和工作区权限;其他模型会话使用 Luna low。共享上下文子任务仍用 DSH。",
4475
+ subagentBackendHint: "Codex 复用订阅登录和工作区权限;默认继承当前订阅模型。开启 DSH 子任务模型选择并新建会话后,可在聊天中指定允许的订阅模型与推理档位;非订阅会话需指定。共享上下文子任务仍用 DSH。",
4476
4476
  subagentBackendUnavailable: "当前宿主缺少子代理服务,请更新 DSH。",
4477
4477
  sketchRecovered: "已恢复未保存草稿",
4478
4478
  sketchRecoveryFailed: "恢复检查点保存失败,请手动保存或导出草稿。",
@@ -4900,7 +4900,7 @@ window.__ModuleLoader__.load({
4900
4900
  subagentBackend_codex: "Codex",
4901
4901
  connectionTitle: "Connection",
4902
4902
  connectionHint: "SSE by default. Experimental WebSocket reuses connections and context transfers and can fall back to SSE on connection failure. Applies to the next request; context limits stay the same.",
4903
- subagentBackendHint: "Codex uses your subscription login, current subscription model and workspace permissions; other model sessions use Luna low. Shared-context subtasks stay in DSH.",
4903
+ subagentBackendHint: "Codex reuses subscription login and workspace permissions, inheriting the current subscription model by default. Enable DSH subtask model selection and start a new session to request an allowed subscription model and reasoning effort in chat; other model sessions require an explicit selection. Shared-context subtasks stay in DSH.",
4904
4904
  subagentBackendUnavailable: "Subagent services are unavailable. Update DSH to use this option.",
4905
4905
  sketchRecovered: "Unsaved sketch recovered",
4906
4906
  sketchRecoveryFailed: "Recovery checkpoint failed. Save or export your draft.",
@@ -7146,7 +7146,7 @@ window.__ModuleLoader__.load({
7146
7146
  }
7147
7147
  //#endregion
7148
7148
  //#region src/version.js
7149
- const PACKAGE_VERSION = "2.1.1-beta.2";
7149
+ const PACKAGE_VERSION = "2.1.2";
7150
7150
  //#endregion
7151
7151
  //#region src/client-recovery.js
7152
7152
  async function recoveryCall(rpc, endpoint, payload = {}, timeoutMs = 1e4) {
package/lib/index.js CHANGED
@@ -468,6 +468,19 @@ function bodyBytes(body) {
468
468
  if (body instanceof Uint8Array) return Buffer.from(body);
469
469
  throw new TypeError("Unsupported Codex OAuth request body");
470
470
  }
471
+ function transportError(error, signal) {
472
+ if (signal?.aborted || error?.name === "AbortError" || error?.code === "ABORT_ERR") return error;
473
+ if (!/^(?:ECONNRESET|ECONNREFUSED|EPIPE|ETIMEDOUT|ENETUNREACH|EHOSTUNREACH|EAI_AGAIN|ERR_STREAM_PREMATURE_CLOSE)$/.test(error?.code ?? "")) return error;
474
+ return Object.assign(new Error(`Network transport failure (${error.code}): ${error.message}`, { cause: error }), { code: error.code });
475
+ }
476
+ function transportResponseBody(response, signal) {
477
+ const body = new PassThrough();
478
+ response.on("error", (error) => body.destroy(transportError(error, signal)));
479
+ body.on("close", () => response.destroy());
480
+ const stream = Readable.toWeb(body);
481
+ response.pipe(body);
482
+ return stream;
483
+ }
471
484
  function fetchThroughProxy(input, init, proxyUrl) {
472
485
  const target = new URL(typeof input === "string" || input instanceof URL ? input : input.url);
473
486
  const body = bodyBytes(init?.body);
@@ -489,13 +502,14 @@ function fetchThroughProxy(input, init, proxyUrl) {
489
502
  205,
490
503
  304
491
504
  ].includes(status);
492
- resolve(new Response(empty ? null : Readable.toWeb(response), {
505
+ if (empty) response.resume();
506
+ resolve(new Response(empty ? null : transportResponseBody(response, init?.signal), {
493
507
  status,
494
508
  statusText: response.statusMessage,
495
509
  headers: responseHeaders
496
510
  }));
497
511
  });
498
- request$1.on("error", reject);
512
+ request$1.on("error", (error) => reject(transportError(error, init?.signal)));
499
513
  if (body) request$1.write(body);
500
514
  request$1.end();
501
515
  });
@@ -1041,16 +1055,34 @@ const MODES = /* @__PURE__ */ new Set([
1041
1055
  "workspace-write",
1042
1056
  "danger-full-access"
1043
1057
  ]);
1044
- function subagentThreadPolicy(parent, policy) {
1058
+ function subagentThreadPolicy(parent, policy, requested = {}) {
1045
1059
  if (!MODES.has(policy?.mode)) throw new Error("DSH subagent sandbox policy is unavailable");
1046
1060
  const selected = parent.session.requestHeader?.()?.config ?? parent.options ?? {};
1047
- const subscription = selected.provider === "openai-codex" && typeof selected.model === "string";
1061
+ for (const key of Object.keys(requested)) if (![
1062
+ "provider",
1063
+ "model",
1064
+ "reasoningEffort"
1065
+ ].includes(key)) throw new Error("Unsupported Codex child option: " + key);
1066
+ if (requested.provider !== void 0 && requested.provider !== "openai-codex") throw new Error("Codex subtasks require the openai-codex provider");
1067
+ const model = requested.model ?? (selected.provider === "openai-codex" ? selected.model : void 0);
1068
+ if (typeof model !== "string" || !model.trim()) throw new Error("Select an openai-codex model for this subtask; the parent model cannot be inherited");
1069
+ const effort = requested.reasoningEffort ?? (requested.model === void 0 ? selected.reasoningEffort : void 0);
1070
+ if (effort !== void 0 && ![
1071
+ "none",
1072
+ "minimal",
1073
+ "low",
1074
+ "medium",
1075
+ "high",
1076
+ "xhigh",
1077
+ "max",
1078
+ "ultra"
1079
+ ].includes(effort)) throw new Error("Unsupported Codex reasoning effort");
1048
1080
  return {
1049
- model: subscription ? selected.model : "gpt-5.6-luna",
1081
+ model,
1050
1082
  modelProvider: "openai",
1051
1083
  approvalPolicy: "never",
1052
1084
  sandbox: policy.mode,
1053
- config: { model_reasoning_effort: subscription ? selected.reasoningEffort ?? "low" : "low" }
1085
+ config: effort === void 0 ? {} : { model_reasoning_effort: effort }
1054
1086
  };
1055
1087
  }
1056
1088
  /** Reuse the official DSH process/turn provider; keep only subscription auth here. */
@@ -1066,7 +1098,7 @@ function createSubscriptionSubagent({ ctx, nativeHome, resolveAuth, store, refre
1066
1098
  provider: {
1067
1099
  name: SUBAGENT_PROVIDER,
1068
1100
  capabilities: {
1069
- agentOptions: false,
1101
+ agentOptions: true,
1070
1102
  outputSchema: false,
1071
1103
  depthLimit: false,
1072
1104
  toolFilter: false,
@@ -1080,7 +1112,7 @@ function createSubscriptionSubagent({ ctx, nativeHome, resolveAuth, store, refre
1080
1112
  const signal = AbortSignal.any([request.signal, controller.signal]);
1081
1113
  let run;
1082
1114
  try {
1083
- const thread = subagentThreadPolicy(request.parent, ctx.sandboxPolicy.resolve({ session: request.parent.session }));
1115
+ const thread = subagentThreadPolicy(request.parent, ctx.sandboxPolicy.resolve({ session: request.parent.session }), request.agentOptions);
1084
1116
  const getTokens = await createSubagentTokens({
1085
1117
  resolveAuth,
1086
1118
  store,
@@ -1125,6 +1157,7 @@ function createSubscriptionSubagent({ ctx, nativeHome, resolveAuth, store, refre
1125
1157
  });
1126
1158
  run = await delegate.start({
1127
1159
  ...request,
1160
+ agentOptions: void 0,
1128
1161
  signal
1129
1162
  });
1130
1163
  const result = run.result.finally(() => active.delete(controller));
@@ -1162,7 +1195,7 @@ function createSubagentBackendSwitcher({ entries, prepare, persist }) {
1162
1195
  const convert = (config) => ({
1163
1196
  ...config,
1164
1197
  provider: SUBAGENT_PROVIDER,
1165
- modelSelectionSettings: false,
1198
+ modelSelectionSettings: true,
1166
1199
  backgroundMode: "one-shot",
1167
1200
  maxDepth: "provider-managed"
1168
1201
  });
@@ -2476,6 +2509,20 @@ function createCodexRpcHandler(coordinator, options = {}) {
2476
2509
  };
2477
2510
  }
2478
2511
  //#endregion
2512
+ //#region src/transport-failure.js
2513
+ function normalizeTransportEvent(event, signal) {
2514
+ if (signal?.aborted || event?.type !== "error" || event.reason !== "error") return event;
2515
+ const message = event.error?.errorMessage;
2516
+ if (typeof message !== "string" || !/^WebSocket closed (?:1006|1011|1012|1013)(?:\s|$)/.test(message)) return event;
2517
+ return {
2518
+ ...event,
2519
+ error: {
2520
+ ...event.error,
2521
+ errorMessage: `Network transport failure: ${message}`
2522
+ }
2523
+ };
2524
+ }
2525
+ //#endregion
2479
2526
  //#region src/pi-ai-runtime.js
2480
2527
  const FAST_SERVICE_TIER = "priority";
2481
2528
  /**
@@ -2559,13 +2606,17 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
2559
2606
  let prepared;
2560
2607
  const step = async (method, value) => {
2561
2608
  const request = await (prepared ??= connection?.prepare(options) ?? Promise.resolve({ options }));
2562
- return runNetwork("model", () => {
2609
+ const result = await runNetwork("model", () => {
2563
2610
  iterator ??= factory(compaction?.requestOptions(request.options) ?? request.options)[Symbol.asyncIterator]();
2564
2611
  return iterator[method]?.(value) ?? (method === "throw" ? Promise.reject(value) : Promise.resolve({
2565
2612
  done: true,
2566
2613
  value
2567
2614
  }));
2568
2615
  }, compaction?.networkOptions(request.network) ?? request.network);
2616
+ return result.done ? result : {
2617
+ ...result,
2618
+ value: normalizeTransportEvent(result.value, request.options?.signal)
2619
+ };
2569
2620
  };
2570
2621
  return {
2571
2622
  [Symbol.asyncIterator]() {
@@ -2593,7 +2644,7 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
2593
2644
  Object.freeze(["0.82.1", "0.85.1"]);
2594
2645
  //#endregion
2595
2646
  //#region src/version.js
2596
- const PACKAGE_VERSION = "2.1.1-beta.2";
2647
+ const PACKAGE_VERSION = "2.1.2";
2597
2648
  const USER_AGENT = `dsh-codex-subscription/${PACKAGE_VERSION}`;
2598
2649
  //#endregion
2599
2650
  //#region src/model-catalog.js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-codex-subscription",
3
- "version": "2.1.1-beta.2",
3
+ "version": "2.1.2",
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",