dsh-codex-subscription 2.6.8 → 2.6.9

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
@@ -106,7 +106,7 @@ This plugin supports the latest DeepSeek Harness release recorded in its package
106
106
  2. Paste this package name, with its version, into the **Package name or address** field:
107
107
 
108
108
  ```text
109
- dsh-codex-subscription@2.6.8
109
+ dsh-codex-subscription@2.6.9
110
110
  ```
111
111
 
112
112
  3. Click **Install** and wait for completion. Follow the page instructions; save your work before restarting if requested.
@@ -118,7 +118,7 @@ Why the version is included: DSH's plugin page only installs versions that are a
118
118
  <summary>Terminal installation (with an existing dsh command)</summary>
119
119
 
120
120
  ```sh
121
- dsh plugin --profile web add dsh-codex-subscription@2.6.8
121
+ dsh plugin --profile web add dsh-codex-subscription@2.6.9
122
122
  ```
123
123
 
124
124
  Follow the restart instructions, then sign in under **Settings → Codex**. Both the Plugins page and the terminal use DSH's installation management.
@@ -131,7 +131,7 @@ Follow the restart instructions, then sign in under **Settings → Codex**. Both
131
131
  After signing in and selecting a Codex model in Web, install the same plugin in the Headless profile:
132
132
 
133
133
  ```sh
134
- dsh plugin --profile headless add dsh-codex-subscription@2.6.8
134
+ dsh plugin --profile headless add dsh-codex-subscription@2.6.9
135
135
  dsh --profile headless "Reply with only the word: ok"
136
136
  ```
137
137
 
@@ -266,7 +266,7 @@ Find this plugin on the DSH **Plugins** page and use its update or uninstall act
266
266
  <summary>Terminal commands</summary>
267
267
 
268
268
  ```sh
269
- dsh plugin --profile web update dsh-codex-subscription@2.6.8
269
+ dsh plugin --profile web update dsh-codex-subscription@2.6.9
270
270
  ```
271
271
 
272
272
  Run only when you want to uninstall:
@@ -282,7 +282,7 @@ dsh plugin --profile web remove dsh-codex-subscription
282
282
  <details>
283
283
  <summary>DSH 0.2.0-rc.2 reports the plugin as incompatible?</summary>
284
284
 
285
- DSH 0.2.0-rc.2 did not exist when any release before 2.2.10 was published, and a published package's compatibility declaration cannot be changed. Install 2.2.10 or later (a bare package name can resolve to an older release during the first 24 hours, so enter `dsh-codex-subscription@2.2.10`) from the **Plugins** page, or run `dsh plugin --profile web update dsh-codex-subscription@2.6.8`, then restart DSH.
285
+ DSH 0.2.0-rc.2 did not exist when any release before 2.2.10 was published, and a published package's compatibility declaration cannot be changed. Install 2.2.10 or later (a bare package name can resolve to an older release during the first 24 hours, so enter `dsh-codex-subscription@2.2.10`) from the **Plugins** page, or run `dsh plugin --profile web update dsh-codex-subscription@2.6.9`, then restart DSH.
286
286
 
287
287
  </details>
288
288
 
package/README.md CHANGED
@@ -106,7 +106,7 @@
106
106
  2. 在 **包名或地址** 输入框中粘贴下面的包名(已带版本号):
107
107
 
108
108
  ```text
109
- dsh-codex-subscription@2.6.8
109
+ dsh-codex-subscription@2.6.9
110
110
  ```
111
111
 
112
112
  3. 点击 **安装**,等待安装完成;按页面提示操作,需要重启时先保存工作。
@@ -118,7 +118,7 @@
118
118
  <summary>终端安装(已能运行 dsh 命令)</summary>
119
119
 
120
120
  ```sh
121
- dsh plugin --profile web add dsh-codex-subscription@2.6.8
121
+ dsh plugin --profile web add dsh-codex-subscription@2.6.9
122
122
  ```
123
123
 
124
124
  安装完成后按提示重启 DSH,再到 **设置 → Codex 订阅** 登录。插件页面和终端均由 DSH 管理安装。
@@ -131,7 +131,7 @@ dsh plugin --profile web add dsh-codex-subscription@2.6.8
131
131
  先在 Web 中完成登录并选择一次 Codex 模型,再把同一个插件安装到 Headless profile:
132
132
 
133
133
  ```sh
134
- dsh plugin --profile headless add dsh-codex-subscription@2.6.8
134
+ dsh plugin --profile headless add dsh-codex-subscription@2.6.9
135
135
  dsh --profile headless "只回复:ok"
136
136
  ```
137
137
 
@@ -295,7 +295,7 @@ DSH 实机设置截图。
295
295
  <summary>终端方式</summary>
296
296
 
297
297
  ```sh
298
- dsh plugin --profile web update dsh-codex-subscription@2.6.8
298
+ dsh plugin --profile web update dsh-codex-subscription@2.6.9
299
299
  ```
300
300
 
301
301
  仅在需要卸载时运行:
@@ -311,7 +311,7 @@ dsh plugin --profile web remove dsh-codex-subscription
311
311
  <details>
312
312
  <summary>DSH 0.2.0-rc.2 提示插件不兼容?</summary>
313
313
 
314
- 2.2.10 之前的所有版本发布时 DSH 0.2.0-rc.2 还不存在,其兼容声明无法事后修改。请安装 2.2.10 或更高版本(只填包名时,发布满 24 小时前可能装到旧版,请直接填 `dsh-codex-subscription@2.2.10`):在 **插件** 页面更新,或运行 `dsh plugin --profile web update dsh-codex-subscription@2.6.8`,然后重启 DSH。
314
+ 2.2.10 之前的所有版本发布时 DSH 0.2.0-rc.2 还不存在,其兼容声明无法事后修改。请安装 2.2.10 或更高版本(只填包名时,发布满 24 小时前可能装到旧版,请直接填 `dsh-codex-subscription@2.2.10`):在 **插件** 页面更新,或运行 `dsh plugin --profile web update dsh-codex-subscription@2.6.9`,然后重启 DSH。
315
315
 
316
316
  </details>
317
317
 
package/lib/client.js CHANGED
@@ -9155,7 +9155,7 @@ window.__ModuleLoader__.load({
9155
9155
  }
9156
9156
  //#endregion
9157
9157
  //#region src/version.js
9158
- const PACKAGE_VERSION = "2.6.8";
9158
+ const PACKAGE_VERSION = "2.6.9";
9159
9159
  //#endregion
9160
9160
  //#region src/client-recovery.js
9161
9161
  async function recoveryCall(rpc, endpoint, payload = {}, timeoutMs = 1e4) {
package/lib/index.js CHANGED
@@ -12,7 +12,7 @@ import { clientRequestSchema } from "@deepseek-ai/dsh-client-connection";
12
12
  import { lstat, mkdir, open, readFile, rename, rm, stat } from "node:fs/promises";
13
13
  import { constants, readFileSync } from "node:fs";
14
14
  import { dirname, join, resolve } from "node:path";
15
- import { pathToFileURL } from "node:url";
15
+ import { fileURLToPath, pathToFileURL } from "node:url";
16
16
  import { defineTool } from "@deepseek-ai/dsh-tools";
17
17
  import * as dshLlm from "@deepseek-ai/dsh-llm";
18
18
  import { createUserMessage } from "@deepseek-ai/dsh-llm";
@@ -2087,7 +2087,7 @@ function inheritedOriginalImageRef(session, assetId) {
2087
2087
  }
2088
2088
  //#endregion
2089
2089
  //#region src/version.js
2090
- const PACKAGE_VERSION = "2.6.8";
2090
+ const PACKAGE_VERSION = "2.6.9";
2091
2091
  const USER_AGENT = `dsh-codex-subscription/${PACKAGE_VERSION}`;
2092
2092
  //#endregion
2093
2093
  //#region src/codex-images.js
@@ -2770,6 +2770,37 @@ function retryPolicyFor(choice, resolve) {
2770
2770
  }
2771
2771
  }
2772
2772
  //#endregion
2773
+ //#region src/request-observer.js
2774
+ const failureOf = (chunk) => chunk?.reason?.kind === "error" ? chunk.reason.failure : void 0;
2775
+ function observed(stream, options, provider) {
2776
+ return (async function* () {
2777
+ try {
2778
+ for await (const chunk of stream(options)) {
2779
+ const failure = failureOf(chunk);
2780
+ if (failure !== void 0 && !options?.signal?.aborted) provider.noteAdapterFailure?.("failure", options, failure);
2781
+ yield chunk;
2782
+ }
2783
+ } catch (error) {
2784
+ if (!options?.signal?.aborted) provider.noteAdapterFailure?.("thrown", options, error);
2785
+ throw error;
2786
+ }
2787
+ })();
2788
+ }
2789
+ function observeAdapter(adapter, provider) {
2790
+ return new Proxy(adapter, { get(target, property) {
2791
+ if (property === "stream") return (options) => observed((o) => target.stream(o), options, provider);
2792
+ if (property === "prepareCall") return async (...args) => {
2793
+ const call = await target.prepareCall(...args);
2794
+ return {
2795
+ ...call,
2796
+ stream: (options) => observed((o) => call.stream(o), options, provider)
2797
+ };
2798
+ };
2799
+ const value = Reflect.get(target, property, target);
2800
+ return typeof value === "function" ? value.bind(target) : value;
2801
+ } });
2802
+ }
2803
+ //#endregion
2773
2804
  //#region src/account-vault.js
2774
2805
  const VERSION = 1;
2775
2806
  const DEFAULT_LABEL = "Account 1";
@@ -3644,8 +3675,134 @@ function createCodexRpcHandler(coordinator, options = {}) {
3644
3675
  };
3645
3676
  }
3646
3677
  //#endregion
3678
+ //#region src/failure-capture.js
3679
+ const KEEP = /* @__PURE__ */ new Set([
3680
+ "method",
3681
+ "type",
3682
+ "role",
3683
+ "name",
3684
+ "api",
3685
+ "provider",
3686
+ "model",
3687
+ "stopReason",
3688
+ "reasoning",
3689
+ "reasoningEffort",
3690
+ "transport",
3691
+ "mimeType",
3692
+ "kind",
3693
+ "effort",
3694
+ "toolChoice",
3695
+ "cacheRetention",
3696
+ "textVerbosity",
3697
+ "serviceTier"
3698
+ ]);
3699
+ const DROP = /* @__PURE__ */ new Set([
3700
+ "apiKey",
3701
+ "headers",
3702
+ "env",
3703
+ "authorization",
3704
+ "token",
3705
+ "signal",
3706
+ "fetch",
3707
+ "cookie"
3708
+ ]);
3709
+ const MAX_DEPTH = 10;
3710
+ const MAX_ARRAY = 40;
3711
+ const MAX_KEYS = 80;
3712
+ const MAX_NODES = 4e3;
3713
+ const MAX_TEXT = 64;
3714
+ const UNDEFINED_MARKER = "$undefined";
3715
+ function redactRequest(value) {
3716
+ let nodes = 0;
3717
+ const walk = (item, key, depth) => {
3718
+ nodes += 1;
3719
+ if (nodes > MAX_NODES) return { $truncated: "nodes" };
3720
+ if (item === void 0) return { [UNDEFINED_MARKER]: true };
3721
+ if (item === null || typeof item === "boolean") return item;
3722
+ if (typeof item === "number") return Number.isFinite(item) ? item : { $number: String(item) };
3723
+ if (typeof item === "bigint" || typeof item === "symbol") return { $type: typeof item };
3724
+ if (typeof item === "function") return { $type: "function" };
3725
+ if (typeof item === "string") {
3726
+ if (KEEP.has(key) && item.length <= MAX_TEXT) return item;
3727
+ return item.length <= MAX_TEXT ? "x".repeat(item.length) : { $text: item.length };
3728
+ }
3729
+ if (depth >= MAX_DEPTH) return { $truncated: "depth" };
3730
+ if (Array.isArray(item)) {
3731
+ const list = [];
3732
+ for (let index = 0; index < Math.min(item.length, MAX_ARRAY); index += 1) list.push(index in item ? walk(item[index], key, depth + 1) : { $hole: true });
3733
+ return item.length > MAX_ARRAY ? [...list, { $more: item.length - MAX_ARRAY }] : list;
3734
+ }
3735
+ if (item instanceof Uint8Array) return { $bytes: item.byteLength };
3736
+ if (typeof item === "object") {
3737
+ const entries = Object.keys(item).filter((name) => !DROP.has(name));
3738
+ const out = {};
3739
+ for (const name of entries.slice(0, MAX_KEYS)) out[name] = walk(item[name], name, depth + 1);
3740
+ if (entries.length > MAX_KEYS) out.$moreKeys = entries.length - MAX_KEYS;
3741
+ return out;
3742
+ }
3743
+ return { $type: typeof item };
3744
+ };
3745
+ return walk(value, "", 0);
3746
+ }
3747
+ //#endregion
3748
+ //#region src/pi-ai-compat.js
3749
+ const versionOf = (specifier) => {
3750
+ try {
3751
+ let path = fileURLToPath(import.meta.resolve(specifier));
3752
+ for (let depth = 0; depth < 6; depth += 1) {
3753
+ path = path.replace(/[\\/][^\\/]+$/u, "");
3754
+ try {
3755
+ const manifest = JSON.parse(readFileSync(`${path}/package.json`, "utf8"));
3756
+ if (typeof manifest.version === "string") return manifest.version;
3757
+ } catch {}
3758
+ }
3759
+ } catch {}
3760
+ };
3761
+ let cached;
3762
+ /** Versions of the pi-ai library and of DSH's adapter this plugin runs against. */
3763
+ function runtimeVersions() {
3764
+ cached ??= {
3765
+ piAi: versionOf("@earendil-works/pi-ai"),
3766
+ adapter: versionOf("@deepseek-ai/dsh-llm-pi-ai")
3767
+ };
3768
+ return cached;
3769
+ }
3770
+ const atLeast087 = (version) => {
3771
+ const match = /^(\d+)\.(\d+)/u.exec(version ?? "");
3772
+ return match !== null && (Number(match[1]) > 0 || Number(match[2]) >= 87);
3773
+ };
3774
+ /** Whether the installed pi-ai understands system messages inside the transcript. */
3775
+ const understandsSystemMessages = (version) => atLeast087(version);
3776
+ const textOf = (content) => typeof content === "string" ? content : Array.isArray(content) ? content.filter((block) => block?.type === "text" && typeof block.text === "string").map((block) => block.text).join("\n") : "";
3777
+ /**
3778
+ * Fold the transcript's leading system messages back into `systemPrompt` and `tools`,
3779
+ * the form every pi-ai release accepts. Messages after the first non-system one stay.
3780
+ */
3781
+ function hoistLeadingSystem(context) {
3782
+ const messages = context?.messages;
3783
+ if (!Array.isArray(messages) || messages[0]?.role !== "system") return context;
3784
+ let end = 0;
3785
+ const texts = context.systemPrompt ? [context.systemPrompt] : [];
3786
+ const tools = [...Array.isArray(context.tools) ? context.tools : []];
3787
+ while (messages[end]?.role === "system") {
3788
+ const message = messages[end];
3789
+ const text = [textOf(message.content), ...Object.values(message.sections ?? {}).filter((value) => typeof value === "string")].filter(Boolean).join("\n\n");
3790
+ if (text !== "") texts.push(text);
3791
+ if (Array.isArray(message.toolsAdded)) tools.push(...message.toolsAdded);
3792
+ end += 1;
3793
+ }
3794
+ const { systemPrompt: _systemPrompt, tools: _tools, ...rest } = context;
3795
+ const systemPrompt = texts.join("\n\n");
3796
+ return {
3797
+ ...rest,
3798
+ ...systemPrompt === "" ? {} : { systemPrompt },
3799
+ ...tools.length === 0 ? {} : { tools },
3800
+ messages: messages.slice(end)
3801
+ };
3802
+ }
3803
+ //#endregion
3647
3804
  //#region src/transport-failure.js
3648
- const TRANSIENT_WEBSOCKET_CLOSE = /^WebSocket closed (?:1006|1011|1012|1013)(?:\s|$)/;
3805
+ const TRANSIENT_WEBSOCKET_CLOSE = /^WebSocket closed (?:1000|1006|1011|1012|1013)(?:\s|$)/;
3649
3806
  const GATEWAY_REPLAY_BUFFER_EXCEEDED = /^\s*exceeded request buffer limit while retrying upstream\s*$/;
3650
3807
  function normalizeTransportEvent(event, signal) {
3651
3808
  if (signal?.aborted || event?.type !== "error" || event.reason !== "error") return event;
@@ -3806,6 +3963,36 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
3806
3963
  sessionModel: 0,
3807
3964
  retries: 0
3808
3965
  };
3966
+ const streamFailure = {
3967
+ count: 0,
3968
+ stage: void 0,
3969
+ frame: void 0,
3970
+ request: void 0,
3971
+ adapter: void 0
3972
+ };
3973
+ const noteAdapterFailure = (kind, adapterOptions, failure) => {
3974
+ try {
3975
+ streamFailure.adapter = {
3976
+ kind,
3977
+ ...typeof failure?.code === "string" ? { code: failure.code.slice(0, 40) } : {},
3978
+ message: String(failure?.message ?? "").slice(0, 160),
3979
+ request: redactRequest(adapterOptions)
3980
+ };
3981
+ } catch {
3982
+ streamFailure.adapter = void 0;
3983
+ }
3984
+ };
3985
+ const noteStreamFailure = (stage, error, source) => {
3986
+ streamFailure.count += 1;
3987
+ streamFailure.stage = stage;
3988
+ try {
3989
+ streamFailure.request = source === void 0 ? void 0 : redactRequest(source);
3990
+ } catch {
3991
+ streamFailure.request = void 0;
3992
+ }
3993
+ const frame = typeof error?.stack === "string" ? /([\w.@-]+[\\/][\w.-]+\.[cm]?[jt]sx?):(\d+):(\d+)/u.exec(error.stack.split("\n").slice(1).join("\n")) : null;
3994
+ streamFailure.frame = frame ? `${frame[1].replaceAll("\\", "/")}:${frame[2]}:${frame[3]}` : void 0;
3995
+ };
3809
3996
  const reviewRoute = (model, context) => {
3810
3997
  if (resolveReviewModel() !== "official" || !isDshAutoReview(context)) return void 0;
3811
3998
  review.requests += 1;
@@ -3860,22 +4047,40 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
3860
4047
  };
3861
4048
  return { [Symbol.asyncIterator]: () => replay ??= run() };
3862
4049
  };
3863
- const networkIterable = (factory, options, direct = false) => {
4050
+ const networkIterable = (factory, options, direct = false, source) => {
3864
4051
  let iterator;
3865
4052
  let prepared;
4053
+ let stage = "prepare";
3866
4054
  const step = async (method, value) => {
3867
- const request = await (prepared ??= (direct ? void 0 : connection?.prepare(options)) ?? Promise.resolve({ options }));
3868
- const result = await runNetwork("model", () => {
3869
- iterator ??= factory(direct ? request.options : compaction?.requestOptions(request.options) ?? request.options)[Symbol.asyncIterator]();
3870
- return iterator[method]?.(value) ?? (method === "throw" ? Promise.reject(value) : Promise.resolve({
3871
- done: true,
3872
- value
3873
- }));
3874
- }, direct ? request.network : compaction?.networkOptions(request.network) ?? request.network);
3875
- return result.done ? result : {
3876
- ...result,
3877
- value: normalizeTransportEvent(result.value, request.options?.signal)
3878
- };
4055
+ try {
4056
+ const request = await (prepared ??= (direct ? void 0 : connection?.prepare(options)) ?? Promise.resolve({ options }));
4057
+ if (stage === "prepare") stage = "request";
4058
+ const result = await runNetwork("model", () => {
4059
+ const next = direct ? request.options : compaction?.requestOptions(request.options) ?? request.options;
4060
+ iterator ??= factory({
4061
+ ...next,
4062
+ async onPayload(payload, requestModel) {
4063
+ stage = "payload";
4064
+ return next.onPayload?.(payload, requestModel);
4065
+ }
4066
+ })[Symbol.asyncIterator]();
4067
+ return iterator[method]?.(value) ?? (method === "throw" ? Promise.reject(value) : Promise.resolve({
4068
+ done: true,
4069
+ value
4070
+ }));
4071
+ }, direct ? request.network : compaction?.networkOptions(request.network) ?? request.network);
4072
+ if (!result.done) {
4073
+ if (result.value?.type === "error" && !request.options?.signal?.aborted) noteStreamFailure(stage, void 0, source);
4074
+ else if (stage === "payload") stage = "stream";
4075
+ }
4076
+ return result.done ? result : {
4077
+ ...result,
4078
+ value: normalizeTransportEvent(result.value, request.options?.signal)
4079
+ };
4080
+ } catch (error) {
4081
+ noteStreamFailure(stage, error, source);
4082
+ throw error;
4083
+ }
3879
4084
  };
3880
4085
  return {
3881
4086
  [Symbol.asyncIterator]() {
@@ -3889,9 +4094,16 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
3889
4094
  throw: (error) => iterator ? step("throw", error) : Promise.reject(error)
3890
4095
  };
3891
4096
  };
3892
- const routed = (method, model, context, options) => {
4097
+ const routed = (method, model, transcript, options) => {
4098
+ const context = understandsSystemMessages(runtimeVersions().piAi) ? transcript : hoistLeadingSystem(transcript);
3893
4099
  const route = reviewRoute(model, context);
3894
- const create = () => route === void 0 ? networkIterable((prepared) => provider[method](model, context, prepared), withPreferences(model, options)) : networkIterable((prepared) => provider[method](model, context, prepared), withReview(route, options), true);
4100
+ const source = {
4101
+ method,
4102
+ model,
4103
+ context,
4104
+ options
4105
+ };
4106
+ const create = () => route === void 0 ? networkIterable((prepared) => provider[method](model, context, prepared), withPreferences(model, options), false, source) : networkIterable((prepared) => provider[method](model, context, prepared), withReview(route, options), true, source);
3895
4107
  return isDshAutoReview(context) ? reviewIterable(create) : create();
3896
4108
  };
3897
4109
  return Object.freeze({
@@ -3903,7 +4115,9 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
3903
4115
  getModels,
3904
4116
  stream: (model, context, options) => routed("stream", model, context, options),
3905
4117
  streamSimple: (model, context, options) => routed("streamSimple", model, context, options),
3906
- reviewCounters: () => ({ ...review })
4118
+ reviewCounters: () => ({ ...review }),
4119
+ streamFailure: () => ({ ...streamFailure }),
4120
+ noteAdapterFailure
3907
4121
  });
3908
4122
  }
3909
4123
  Object.freeze([
@@ -4849,6 +5063,15 @@ function safeRequests(network) {
4849
5063
  }
4850
5064
  return result;
4851
5065
  }
5066
+ /** pi-ai and DSH's adapter come from the host; a profile can pair an adapter with an older library, so the report names both. */
5067
+ function libraryVersions() {
5068
+ const { piAi, adapter } = runtimeVersions();
5069
+ const valid = (value) => typeof value === "string" && /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]{1,32})?$/u.test(value);
5070
+ return {
5071
+ ...valid(piAi) ? { piAi } : {},
5072
+ ...valid(adapter) ? { adapter } : {}
5073
+ };
5074
+ }
4852
5075
  /** Build a support report that deliberately excludes OAuth and account metadata. */
4853
5076
  async function createSubscriptionDiagnostics({ auth, preferences, login = { phase: "idle" }, network, modelCatalog, connection, compaction, review, inspectionOptions, operations, runtimeManagement, storage, tools }) {
4854
5077
  const collected = {};
@@ -4914,6 +5137,26 @@ async function createSubscriptionDiagnostics({ auth, preferences, login = { phas
4914
5137
  "retries"
4915
5138
  ]) : void 0
4916
5139
  ],
5140
+ [
5141
+ "streamFailure",
5142
+ "transport",
5143
+ () => {
5144
+ const value = review?.streamFailure?.();
5145
+ if (!Number.isSafeInteger(value?.count)) return void 0;
5146
+ return {
5147
+ count: value.count,
5148
+ ...[
5149
+ "prepare",
5150
+ "request",
5151
+ "payload",
5152
+ "stream"
5153
+ ].includes(value.stage) ? { stage: value.stage } : {},
5154
+ ...typeof value.frame === "string" && /^[\w.@/-]{1,120}:\d+:\d+$/u.test(value.frame) ? { frame: value.frame } : {},
5155
+ ...value.request && typeof value.request === "object" && JSON.stringify(value.request).length <= 12e4 ? { request: value.request } : {},
5156
+ ...value.adapter && typeof value.adapter === "object" && JSON.stringify(value.adapter).length <= 12e4 ? { adapter: value.adapter } : {}
5157
+ };
5158
+ }
5159
+ ],
4917
5160
  [
4918
5161
  "operations",
4919
5162
  "transport",
@@ -5007,7 +5250,8 @@ async function createSubscriptionDiagnostics({ auth, preferences, login = { phas
5007
5250
  node: process.version,
5008
5251
  platform: process.platform,
5009
5252
  arch: process.arch,
5010
- ...hostDshVersion() ? { dsh: hostDshVersion() } : {}
5253
+ ...hostDshVersion() ? { dsh: hostDshVersion() } : {},
5254
+ ...libraryVersions()
5011
5255
  },
5012
5256
  account,
5013
5257
  login,
@@ -5017,6 +5261,7 @@ async function createSubscriptionDiagnostics({ auth, preferences, login = { phas
5017
5261
  ...collected.websocket ? { websocket: collected.websocket } : {},
5018
5262
  ...collected.compaction ? { compaction: collected.compaction } : {},
5019
5263
  ...collected.review ? { review: collected.review } : {},
5264
+ ...collected.streamFailure ? { streamFailure: collected.streamFailure } : {},
5020
5265
  ...catalog && ["unavailable", "online"].includes(catalog.source) && [
5021
5266
  "idle",
5022
5267
  "refreshing",
@@ -6745,7 +6990,7 @@ function apply(ctx, config = {}) {
6745
6990
  auth: adapterAuth,
6746
6991
  resolveAttachments: () => ctx.get?.("attachments")
6747
6992
  });
6748
- ctx.llm.registerAdapter([PROVIDER], compaction.wrapAdapter(adapter));
6993
+ ctx.llm.registerAdapter([PROVIDER], observeAdapter(compaction.wrapAdapter(adapter), provider));
6749
6994
  const currentAgent = () => ctx.get?.("agents")?.currentInitiator?.();
6750
6995
  const codexSearch = createCodexSearchProvider({
6751
6996
  resolvePreferences: () => readCapabilitySettings(settings.get()),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-codex-subscription",
3
- "version": "2.6.8",
3
+ "version": "2.6.9",
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",