dsh-grok-subscription 1.1.2 → 1.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.2.0 — 2026-09-28
4
+
5
+ - Fix **the host's official pi-ai adapter never serving the route**. `ctx.llm.registerAdapter` refuses a second adapter for a provider that already has one (`DUPLICATE_ADAPTER`, all-or-nothing) in every Host this plugin supports, while the plugin registered its bundled adapter synchronously and then re-registered the same `grok-build` route from the deferred upgrade. That throw landed in the upgrade's `catch` and was logged at warn level, so **every release since 0.1.10 — the one that introduced the bundled-then-upgrade design — ran the bundled adapter** while Settings reported `Active path: bundled fallback`. The upgrade now releases the bundled registration and claims the route again in one synchronous step, and restores the bundled adapter if the Host refuses the replacement, so the route is never left unserved. This defect predates 1.1.3 and is unrelated to the 0.2.0 compatibility gate that release fixed. Reported in 1.1.3's release notes and fixed here.
6
+ - Pin the request fields this plugin owns on the pi-ai path, instead of inheriting pi-ai's defaults. `withEncryptedReasoningInclude` (the single seam that injects `include: ['reasoning.encrypted_content']` into `samplingParams`, which pi-ai assigns over the assembled body last) becomes `withGrokRequestSemantics` and now also pins `prompt_cache_key` to the same `grok:<sessionId>` value the bundled adapter builds. A profile that disables caching (`cacheRetention: 'none'`) is left alone: the plugin never switches a cache back on.
7
+ - **Auxiliary requests deliberately share the session's cache key.** `dsh-llm-pi-ai` forwards only `sessionId` from `GenerateOptions` into pi-ai, so compaction and session-title calls arrive with no purpose marker; isolating them would mean suffixing the session id, which pi-ai also writes into the `session_id` and `x-client-request-id` headers. Measured against the live proxy, isolation does not pay: after a large auxiliary call a repeated chat request still read the full cached prefix in 4 of 5 shared-key trials versus 2 of 5 isolated ones, matching a control run with no auxiliary call at all. The bundled adapter keeps its own `grok:compaction:<sessionId>` scheme; this path keeps the shared key, and the guide says so.
8
+ - Add `DSH_GROK_ADAPTER=fallback` as a documented rollback. It keeps the bundled adapter even where the Host's official one is available, without waiting for a release, and is read from DSH's own environment (`~/.dsh/.env`).
9
+ - Verified on the real 0.2.0-rc.1 desktop runtime against the live subscription. Diagnostics now read `pi-ai` with `hostPeersResolved: true`. A three-turn conversation using the Host's own durable message shape (the accumulator's blocks plus `createAssistantMessage` with its replay state) answered `stored` → `42` → `84`, proving encrypted-reasoning replay survives the switch, with `cacheReadTokens` climbing 1152 → 1280 → 1408. A tool turn returned `finish: tool-calls` with `get_weather {"city":"Paris"}`. A `purpose: 'compaction'` turn completed normally. The rollback switch was exercised live: `fallback` serves the bundled adapter, unset and any other value serve `PiAiAdapter`.
10
+ - `tests/pi-ai-request-body.test.mjs` drives the real `@earendil-works/pi-ai` Responses API through the plugin's wrapper with a stubbed transport and asserts the outgoing body — `include`, `prompt_cache_key`, `store: false`, `model`, and the converted input — so a pi-ai release that stops honouring `samplingParams` fails CI instead of silently dropping both fields. `tests/pi-ai-request-semantics.test.mjs` covers the wrapper directly (including the disabled-cache case), and `tests/adapter-upgrade.test.mjs` models the Host's registry rule and the rollback switch. All eight new assertions fail against 1.1.3.
11
+ - No session, login, renewal, model-routing, quota, or proxy changes. The bundled adapter is still shipped and still the automatic fallback. Restart DSH fully after updating.
12
+
13
+ ## 1.1.3 — 2026-09-28
14
+
15
+ - Fix **the plugin disappearing from the desktop app after it updated to DSH 0.2.0-rc.1**. DSH 0.2.0 gates every profile entry on the plugin's `@deepseek-ai/dsh*` peer ranges (`evaluatePluginCompatibility` in `@deepseek-ai/dsh-app-boot`) and drops the whole bundle before any plugin code loads when one of them does not admit the running version. This plugin declared `^0.1.5-rc.2`, which is `<0.2.0`, so the Host reported `skipping profile bundle "dsh-grok-subscription": Plugin dsh-grok-subscription@1.1.2 is incompatible with dsh 0.2.0-rc.1` and started without a `grok-build` route, without a Settings section, and without any error in the UI. Reproduced against the real desktop runtime, and confirmed fixed with the same `dsh --profile <name> --dump-config`: the composition now emits the `grok-subscription` row.
16
+ - Widen each DSH peer to `>=0.1.5-rc.2 <0.3.0-0`: a span across the 0.1 and 0.2 lines rather than a range that silently expires on the next Host bump. Nothing the previous range admitted is dropped, and 0.3.0 prereleases stay refused, so the next minor gets a fresh verification instead of another silent removal.
17
+ - Verified on the real 0.2.0-rc.1 desktop runtime with a live Host: `grok-subscription/status` and `grok-subscription/plugin/version` answer over the Host's own `/api` routes, the account is signed in, the live catalog lists all four models, the weekly quota reads, and a minimal live generation through the registered route returned a complete stream (`OK`, `finish: stop`, usage). No model-routing, authentication, proxy, or quota changes: the adapter this release runs is the same one 1.1.2 ran.
18
+ - `tests/host-compatibility.test.mjs` checks every DSH peer against a runtime matrix (0.1.5-rc.2 … 0.2.14 admitted, 0.3.0 prereleases refused) and pins the shared span; it fails against 1.1.2.
19
+ - Add a Troubleshooting entry to both guides for the next time a Host update removes the plugin: where the Host reports it, and why a version exemption is the wrong remedy.
20
+ - Restart DSH fully after updating.
21
+
3
22
  ## 1.1.2 — 2026-09-28
4
23
 
5
24
  - Fix **Windows reporting "no grok CLI"** with the official CLI installed. Detection probed for a file literally named `grok`, but `fs.existsSync` never applies Windows' `PATHEXT` resolution, so the installed `grok.exe` was invisible: `resolveGrokBin()` fell back to the bare name, `grokCliAvailable()` returned `false`, and every CLI-backed path — session pull, CLI/device-code login, automatic renewal — was short-circuited before it ran. Settings showed the orange "CLI not found" warning and the plugin stayed on its built-in fallback adapter, even though `spawn("grok")` itself works on Windows.
package/docs/guide.en.md CHANGED
@@ -6,7 +6,7 @@ For quick setup, see the [README](../README.en.md#install). This guide covers de
6
6
 
7
7
  ## Installation and compatibility
8
8
 
9
- You need DeepSeek Harness, the official Grok Build CLI, and an account with Grok Build access. The plugin declares Node.js `^22.19.0 || >=24.0.0`; DSH peers use `^0.1.5-rc.2`. See [package.json](../package.json) for the full requirements. Declared compatibility is not a claim that every version has passed live verification.
9
+ You need DeepSeek Harness, the official Grok Build CLI, and an account with Grok Build access. The plugin declares Node.js `^22.19.0 || >=24.0.0`; DSH peers use `>=0.1.5-rc.2 <0.3.0-0`, which spans the whole 0.1 and 0.2 lines. See [package.json](../package.json) for the full requirements. Declared compatibility is not a claim that every version has passed live verification.
10
10
 
11
11
  **Install from npm:**
12
12
 
@@ -18,7 +18,7 @@ dsh plugin --profile web list dsh-grok-subscription --depth 0
18
18
  For reproducibility, pin a published version, for example:
19
19
 
20
20
  ```sh
21
- dsh plugin --profile web add dsh-grok-subscription@1.1.2
21
+ dsh plugin --profile web add dsh-grok-subscription@1.2.0
22
22
  ```
23
23
 
24
24
  **Install from GitHub:**
@@ -80,7 +80,7 @@ These exact IDs come from `IMAGE_INPUT_MODEL_IDS` in [constants.js](../src/const
80
80
 
81
81
  Paste or attach an image in the composer. DSH's attachment service processes it within pixel and byte budgets; over-budget images may degrade to a text description. Do not assume every image is sent at its original resolution.
82
82
 
83
- Both the host's pi-ai adapter and the bundled fallback have image-handling paths, but both depend on the host attachment capability. The **Active path** row in Settings shows the adapter and whether image input is available. After an update, a refreshed browser can still be using an old adapter if the Host was not restarted.
83
+ From 1.2.0 the plugin runs the host's official pi-ai adapter, which owns the image pipeline (attachment resolution plus pixel and byte budgets). The bundled adapter stays as the automatic fallback: it is what serves the route if the pi-ai packages are missing, or if the Host refuses the hand-over. The **Active path** row in Settings names the adapter actually serving the route, and whether image input is available. After an update, a refreshed browser can still be using an old adapter if the Host was not restarted. To pin the bundled adapter deliberately — for instance if a Host adapter misbehaves on your account — set `DSH_GROK_ADAPTER=fallback` in `~/.dsh/.env` and restart DSH.
84
84
 
85
85
  ## Quota and caching
86
86
 
@@ -88,7 +88,7 @@ Usage is read through the undocumented `/v1/billing?format=credits` endpoint and
88
88
 
89
89
  The composer badge appears only for `grok-build` with a successful usage read; hover or click for weekly quota and its reset time. Missing data does not mean zero quota. A failed read does not invent percentages or independently block chat.
90
90
 
91
- For prefix caching, the plugin keeps a stable `prompt_cache_key` and tool ordering within a DSH session, and the bundled adapter preserves `reasoning.encrypted_content`. These are request-construction measures, not a guarantee of backend cache hits or quota savings. No invented hit rate is reported. See [adapter.js](../src/adapter.js).
91
+ For prefix caching, the plugin pins one stable `prompt_cache_key` per DSH session on **both** adapter paths — the bundled adapter builds it, and on the host's pi-ai path the plugin assigns the same `grok:<sessionId>` value into the request. Tool ordering stays stable. Auxiliary requests (compaction, session titles) share the session's key rather than taking a separate one; measured against the proxy, isolating them did not improve the chat prefix's cache reads. These are request-construction measures, not a guarantee of backend cache hits or quota savings. No invented hit rate is reported. See [adapter.js](../src/adapter.js).
92
92
 
93
93
  ## Headless usage
94
94
 
@@ -124,6 +124,8 @@ That task makes a real model request and uses the selected service's quota; it i
124
124
 
125
125
  **No response on an old release.** Version `1.0.0` had a tool-call serialization defect fixed in `1.0.1`; older versions may also lack later renewal fixes. Update to the current published version before diagnosing a persistent problem rather than attributing every missing response to that old defect.
126
126
 
127
+ **The plugin vanished from Settings after a DSH update.** From 0.2.0 DSH refuses a plugin whose `@deepseek-ai/dsh*` peer ranges do not admit the running version, and it drops the whole bundle before any plugin code loads: no `grok-build` route, no Settings section, and nothing in the panel to explain it. The Host writes `skipping profile bundle "dsh-grok-subscription"` to its own stderr, and `dsh --profile web --dump-config` omits the `grok-subscription` row. Update the plugin rather than granting a version exemption: an exemption re-enables a build that was never checked against that Host.
128
+
127
129
  ## Updates and sign-out
128
130
 
129
131
  For npm installs, update in Settings or run `dsh plugin --profile web add dsh-grok-subscription@latest`. For GitHub-source installs, run `dsh plugin --profile web update dsh-grok-subscription`. For local links, pull, test, and rebuild the checkout. Restart DSH afterwards.
@@ -132,7 +134,7 @@ In the desktop app the `desktop` profile is owned exclusively by the Electron ap
132
134
 
133
135
  ```sh
134
136
  cd "$HOME/.dsh/profiles/desktop" # Windows: cd "$env:USERPROFILE\.dsh\profiles\desktop"
135
- pnpm add --save-exact dsh-grok-subscription@1.1.2
137
+ pnpm add --save-exact dsh-grok-subscription@1.2.0
136
138
  ```
137
139
 
138
140
  Then quit and restart the desktop app completely. After a successful update the profile's `package.json` dependency should show the target version while its `dsh.profile.bundles` entry is unchanged. Refreshing the browser is not enough: without a Host restart the old version keeps loading.
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## 安装与兼容性
8
8
 
9
- 需要 DeepSeek Harness、官方 Grok Build CLI,以及当前具有 Grok Build 使用资格的订阅账号。插件的 Node.js 要求为 `^22.19.0 || >=24.0.0`,DSH peer 声明以 [package.json](../package.json) 为准;其中 DSH 依赖使用 `^0.1.5-rc.2`。声明范围不等于所有版本都已经过实机验证。
9
+ 需要 DeepSeek Harness、官方 Grok Build CLI,以及当前具有 Grok Build 使用资格的订阅账号。插件的 Node.js 要求为 `^22.19.0 || >=24.0.0`,DSH peer 声明以 [package.json](../package.json) 为准;其中 DSH 依赖使用 `>=0.1.5-rc.2 <0.3.0-0`,覆盖 0.1 与 0.2 全线。声明范围不等于所有版本都已经过实机验证。
10
10
 
11
11
  **npm 安装:**
12
12
 
@@ -18,7 +18,7 @@ dsh plugin --profile web list dsh-grok-subscription --depth 0
18
18
  需要可重复安装时,固定已发布版本,例如:
19
19
 
20
20
  ```sh
21
- dsh plugin --profile web add dsh-grok-subscription@1.1.2
21
+ dsh plugin --profile web add dsh-grok-subscription@1.2.0
22
22
  ```
23
23
 
24
24
  **GitHub 来源安装:**
@@ -80,7 +80,7 @@ grok-4.6
80
80
 
81
81
  在输入框粘贴或附加图片后,DSH 的附件服务会按像素与体积预算处理。图片超出可用预算时可能降级为文本说明;不要假设每张原图都以原始分辨率发出。
82
82
 
83
- 宿主官方 pi-ai 适配器和内置回退适配器都有对应图片通路,但都依赖宿主附件能力。设置页的 **运行通路** 会显示当前适配器和图片输入是否可用。更新后只有界面刷新、Host 未重启时,可能仍运行旧适配器。
83
+ 1.2.0 起,插件默认运行宿主官方的 pi-ai 适配器,图片通路(附件解析与像素、体积预算)由它负责。内置适配器保留为自动回退:pi-ai 相关包缺失、或宿主拒绝交接时,仍由它服务该路由。设置页的 **运行通路** 会显示实际在服务的适配器和图片输入是否可用。更新后只有界面刷新、Host 未重启时,可能仍运行旧适配器。若要主动固定在内置适配器(例如宿主适配器在你的账号上表现异常),在 `~/.dsh/.env` 里设置 `DSH_GROK_ADAPTER=fallback` 并重启 DSH。
84
84
 
85
85
  ## 额度与缓存
86
86
 
@@ -88,7 +88,7 @@ grok-4.6
88
88
 
89
89
  输入框徽章仅在当前 provider 为 `grok-build` 且用量读取成功时显示,悬停或点击查看每周余量与重置时间。缺失数据不是额度为零;读取失败不会编造百分比,也不会因为单独的额度读取故障阻止聊天。
90
90
 
91
- 前缀缓存方面,插件为同一 DSH 会话保持稳定的 `prompt_cache_key` 和工具顺序,内置回退适配器保留 `reasoning.encrypted_content`。这些是请求构造措施,不保证服务端缓存命中或节省额度;项目不提供虚构的命中率。实现见 [adapter.js](../src/adapter.js)。
91
+ 前缀缓存方面,插件在**两条通路**上都为同一 DSH 会话固定同一个 `prompt_cache_key`:内置适配器自行构造,宿主 pi-ai 通路上插件把同样的 `grok:<sessionId>` 注入请求;工具顺序保持稳定。压缩、会话标题这类辅助请求与会话共用同一个 key,而不是另开一个——对代理实测下来,隔离它们并不会提高聊天前缀的缓存命中。这些是请求构造措施,不保证服务端缓存命中或节省额度;项目不提供虚构的命中率。实现见 [adapter.js](../src/adapter.js)。
92
92
 
93
93
  ## Headless 使用
94
94
 
@@ -124,6 +124,8 @@ dsh --profile headless "只回复:ok"
124
124
 
125
125
  **旧版本发消息无回复。** `1.0.0` 存在已在 `1.0.1` 修正的工具调用序列化问题;旧版本也可能缺少后续续期修复。先更新到当前发布版,再定位仍然存在的问题,不要把所有无回复都归因于旧缺陷。
126
126
 
127
+ **DSH 更新后插件从设置页消失。** 0.2.0 起,插件的 `@deepseek-ai/dsh*` peer 范围若不包含当前运行版本,DSH 会在加载任何插件代码之前丢掉整个 bundle:既没有 `grok-build` 路由,也没有设置分区,界面里没有任何提示。Host 自己的 stderr 会输出 `skipping profile bundle "dsh-grok-subscription"`,`dsh --profile web --dump-config` 里也不会出现 `grok-subscription` 行。此时应更新插件,而不是授予版本豁免——豁免会重新启用一个从未针对该 Host 验证过的构建。
128
+
127
129
  ## 更新与登出
128
130
 
129
131
  npm 安装可在设置页更新,或运行 `dsh plugin --profile web add dsh-grok-subscription@latest`。GitHub 来源安装可运行 `dsh plugin --profile web update dsh-grok-subscription`。本地链接安装则拉取对应 checkout、测试并构建。更新后手动重启 DSH。
@@ -132,7 +134,7 @@ npm 安装可在设置页更新,或运行 `dsh plugin --profile web add dsh-gr
132
134
 
133
135
  ```sh
134
136
  cd "$HOME/.dsh/profiles/desktop" # Windows: cd "$env:USERPROFILE\.dsh\profiles\desktop"
135
- pnpm add --save-exact dsh-grok-subscription@1.1.2
137
+ pnpm add --save-exact dsh-grok-subscription@1.2.0
136
138
  ```
137
139
 
138
140
  然后完全退出并重启桌面版。更新成功后该 profile 的 `package.json` 里依赖应变为目标版本,`dsh.profile.bundles` 条目保持不变。仅刷新网页不够:Host 未重启时仍会加载旧版本。
package/lib/client.js CHANGED
@@ -39,7 +39,7 @@ var import_react2 = require("react");
39
39
  var zh = {
40
40
  nav: "Grok \u8BA2\u9605",
41
41
  title: "Grok \u8BA2\u9605",
42
- subtitle: "\u7528 SuperGrok / X Premium\uFF08Grok Build\uFF09\u4F1A\u8BDD\uFF0C\u800C\u4E0D\u662F XAI_API_KEY\u3002\xB7 1.1.2",
42
+ subtitle: "\u7528 SuperGrok / X Premium\uFF08Grok Build\uFF09\u4F1A\u8BDD\uFF0C\u800C\u4E0D\u662F XAI_API_KEY\u3002\xB7 1.2.0",
43
43
  signedIn: "\u5DF2\u767B\u5F55",
44
44
  signedOut: "\u672A\u767B\u5F55",
45
45
  account: "\u8D26\u6237",
@@ -119,7 +119,7 @@ var zh = {
119
119
  var en = {
120
120
  nav: "Grok Subscription",
121
121
  title: "Grok Subscription",
122
- subtitle: "Use a SuperGrok / X Premium (Grok Build) session, not XAI_API_KEY. \xB7 1.1.2",
122
+ subtitle: "Use a SuperGrok / X Premium (Grok Build) session, not XAI_API_KEY. \xB7 1.2.0",
123
123
  signedIn: "Signed in",
124
124
  signedOut: "Signed out",
125
125
  account: "Account",
package/lib/index.js CHANGED
@@ -1473,14 +1473,18 @@ function buildAuthConfig() {
1473
1473
  }
1474
1474
  };
1475
1475
  }
1476
- function withEncryptedReasoningInclude(api) {
1477
- const inject2 = (options) => ({
1478
- ...options,
1479
- samplingParams: {
1480
- ...options?.samplingParams,
1481
- include: ["reasoning.encrypted_content"]
1482
- }
1483
- });
1476
+ function withGrokRequestSemantics(api) {
1477
+ const inject2 = (options) => {
1478
+ const cacheKey = options?.cacheRetention === "none" ? void 0 : promptCacheKey(options);
1479
+ return {
1480
+ ...options,
1481
+ samplingParams: {
1482
+ ...options?.samplingParams,
1483
+ include: ["reasoning.encrypted_content"],
1484
+ ...cacheKey === void 0 ? {} : { prompt_cache_key: cacheKey }
1485
+ }
1486
+ };
1487
+ };
1484
1488
  return {
1485
1489
  stream: (model, context, options) => api.stream(model, context, inject2(options)),
1486
1490
  streamSimple: (model, context, options) => api.streamSimple(model, context, inject2(options))
@@ -1545,7 +1549,7 @@ async function createGrokBuildAdapter(session, options = {}) {
1545
1549
  if (!responsesApi) {
1546
1550
  return { adapter: asHostAdapter(duck), kind: "custom-mvp", note: "openai-responses API module is unavailable; using the custom adapter." };
1547
1551
  }
1548
- responsesApi = withEncryptedReasoningInclude(responsesApi);
1552
+ responsesApi = withGrokRequestSemantics(responsesApi);
1549
1553
  const store = createStore(session);
1550
1554
  const authModels = piAi.createModels({
1551
1555
  credentials: store,
@@ -2693,6 +2697,34 @@ function softService(ctx, key) {
2693
2697
  }
2694
2698
  return void 0;
2695
2699
  }
2700
+ function registerProviderAdapter(ctx, adapter) {
2701
+ const handle = ctx.llm.registerAdapter([PROVIDER_ID], adapter);
2702
+ return typeof handle === "function" ? handle : void 0;
2703
+ }
2704
+ function upgradeProviderAdapter(ctx, adapter, registration) {
2705
+ const previous = registration.adapter;
2706
+ registration.release?.();
2707
+ registration.release = void 0;
2708
+ registration.adapter = void 0;
2709
+ try {
2710
+ registration.release = registerProviderAdapter(ctx, adapter);
2711
+ registration.adapter = adapter;
2712
+ } catch (error) {
2713
+ if (previous !== void 0) {
2714
+ try {
2715
+ registration.release = registerProviderAdapter(ctx, previous);
2716
+ registration.adapter = previous;
2717
+ } catch {
2718
+ registration.release = void 0;
2719
+ }
2720
+ }
2721
+ throw error;
2722
+ }
2723
+ }
2724
+ function adapterOverride(env = process.env) {
2725
+ const value = typeof env?.DSH_GROK_ADAPTER === "string" ? env.DSH_GROK_ADAPTER.trim().toLowerCase() : "";
2726
+ return value === "fallback" ? "fallback" : void 0;
2727
+ }
2696
2728
  function attachmentResolver(ctx) {
2697
2729
  return () => {
2698
2730
  try {
@@ -2742,11 +2774,13 @@ function apply(ctx, options = {}) {
2742
2774
  });
2743
2775
  const resolveAttachments = attachmentResolver(ctx);
2744
2776
  const createSync = options.createSync ?? createGrokBuildAdapterSync;
2777
+ const registration = { adapter: void 0, release: void 0 };
2745
2778
  try {
2746
2779
  const created = createSync(session, { resolveAttachments });
2747
2780
  if (created.note) ctx.logger?.debug?.(created.note);
2748
2781
  adapterState.kind = created.kind;
2749
- ctx.llm.registerAdapter([PROVIDER_ID], created.adapter);
2782
+ registration.adapter = created.adapter;
2783
+ registration.release = registerProviderAdapter(ctx, created.adapter);
2750
2784
  notifyCatalogChange();
2751
2785
  } catch (error) {
2752
2786
  ctx.logger?.warn?.(
@@ -2755,15 +2789,16 @@ function apply(ctx, options = {}) {
2755
2789
  );
2756
2790
  }
2757
2791
  const defer = options.defer ?? scheduleDeferred2;
2792
+ const deferredOptions = adapterOverride() === "fallback" ? { ...options, skipUpgrade: true } : options;
2758
2793
  defer(() => {
2759
- void deferredBoot(ctx, session, notifyCatalogChange, options, adapterState);
2794
+ void deferredBoot(ctx, session, notifyCatalogChange, deferredOptions, adapterState, registration);
2760
2795
  });
2761
2796
  ctx.inject(["connection"], (connectionContext) => connectionContext.effect(
2762
2797
  () => registerSubscriptionTransport(connectionContext.connection, handler),
2763
2798
  "grok-subscription: host-only account RPC"
2764
2799
  ));
2765
2800
  }
2766
- async function deferredBoot(ctx, session, notifyCatalogChange, options = {}, adapterState) {
2801
+ async function deferredBoot(ctx, session, notifyCatalogChange, options = {}, adapterState, registration) {
2767
2802
  if (!options.skipSettings) {
2768
2803
  await tryRegisterSettings(ctx);
2769
2804
  }
@@ -2794,7 +2829,8 @@ async function deferredBoot(ctx, session, notifyCatalogChange, options = {}, ada
2794
2829
  const created = await createAsync(session, { ...options.adapterOptions, resolveAttachments: attachmentResolver(ctx) });
2795
2830
  if (created.kind === "pi-ai") {
2796
2831
  if (created.note) ctx.logger?.warn?.(created.note);
2797
- ctx.llm.registerAdapter([PROVIDER_ID], created.adapter);
2832
+ if (registration) upgradeProviderAdapter(ctx, created.adapter, registration);
2833
+ else ctx.llm.registerAdapter([PROVIDER_ID], created.adapter);
2798
2834
  if (adapterState) {
2799
2835
  adapterState.kind = created.kind;
2800
2836
  adapterState.upgraded = true;
@@ -2832,10 +2868,13 @@ export {
2832
2868
  DISPLAY_NAME,
2833
2869
  DISPLAY_NAME_ZH,
2834
2870
  PROVIDER_ID,
2871
+ adapterOverride,
2835
2872
  apply,
2836
2873
  deferredBoot,
2837
2874
  inject,
2838
2875
  name,
2876
+ registerProviderAdapter,
2839
2877
  scheduleDeferred2 as scheduleDeferred,
2840
- softService
2878
+ softService,
2879
+ upgradeProviderAdapter
2841
2880
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-grok-subscription",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "Use a SuperGrok or X Premium Grok Build subscription in DeepSeek Harness",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -59,20 +59,20 @@
59
59
  "node": "^22.19.0 || >=24.0.0"
60
60
  },
61
61
  "peerDependencies": {
62
- "@deepseek-ai/dsh-api-remotes": "^0.1.5-rc.2",
63
- "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.2",
64
- "@deepseek-ai/dsh-client-locale": "^0.1.5-rc.2",
65
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-rc.2",
66
- "@deepseek-ai/dsh-client-ui-model-selection": "^0.1.5-rc.2",
67
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.5-rc.2",
68
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.5-rc.2",
69
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.5-rc.2",
70
- "@deepseek-ai/dsh-credentials": "^0.1.5-rc.2",
71
- "@deepseek-ai/dsh-llm": "^0.1.5-rc.2",
72
- "@deepseek-ai/dsh-llm-pi-ai": "^0.1.5-rc.2",
73
- "@deepseek-ai/dsh-settings": "^0.1.5-rc.2",
74
- "@deepseek-ai/dsh-web": "^0.1.5-rc.2",
75
- "@earendil-works/pi-ai": "^0.82.1",
62
+ "@deepseek-ai/dsh-api-remotes": ">=0.1.5-rc.2 <0.3.0-0",
63
+ "@deepseek-ai/dsh-client-connection": ">=0.1.5-rc.2 <0.3.0-0",
64
+ "@deepseek-ai/dsh-client-locale": ">=0.1.5-rc.2 <0.3.0-0",
65
+ "@deepseek-ai/dsh-client-ui-conversation": ">=0.1.5-rc.2 <0.3.0-0",
66
+ "@deepseek-ai/dsh-client-ui-model-selection": ">=0.1.5-rc.2 <0.3.0-0",
67
+ "@deepseek-ai/dsh-client-ui-primitives": ">=0.1.5-rc.2 <0.3.0-0",
68
+ "@deepseek-ai/dsh-client-ui-settings": ">=0.1.5-rc.2 <0.3.0-0",
69
+ "@deepseek-ai/dsh-client-ui-slots": ">=0.1.5-rc.2 <0.3.0-0",
70
+ "@deepseek-ai/dsh-credentials": ">=0.1.5-rc.2 <0.3.0-0",
71
+ "@deepseek-ai/dsh-llm": ">=0.1.5-rc.2 <0.3.0-0",
72
+ "@deepseek-ai/dsh-llm-pi-ai": ">=0.1.5-rc.2 <0.3.0-0",
73
+ "@deepseek-ai/dsh-settings": ">=0.1.5-rc.2 <0.3.0-0",
74
+ "@deepseek-ai/dsh-web": ">=0.1.5-rc.2 <0.3.0-0",
75
+ "@earendil-works/pi-ai": "0.82.1 || 0.85.1",
76
76
  "react": "^18.2.0",
77
77
  "react-dom": "^18.2.0"
78
78
  },
@@ -127,9 +127,11 @@
127
127
  }
128
128
  },
129
129
  "devDependencies": {
130
+ "@earendil-works/pi-ai": "0.85.1",
130
131
  "esbuild": "^0.25.0",
131
132
  "react": "^18.3.1",
132
- "react-dom": "^18.3.1"
133
+ "react-dom": "^18.3.1",
134
+ "semver": "^7.8.5"
133
135
  },
134
136
  "author": "BaronCyrus",
135
137
  "repository": {