@dan-ai-studio/dshopencodego 0.1.17 → 0.1.18

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
@@ -162,7 +162,7 @@ The `engines.dsh` field is informational for readers and package managers; **DSH
162
162
  Things to keep in mind when maintaining this:
163
163
 
164
164
  - **Required versus optional peers**: six of the eighteen are marked `optional` (`dsh-api-remotes`, `dsh-client-locale`, `dsh-client-store`, `dsh-client-ui-model-selection`, `dsh-client-ui-settings`, `dsh-client-ui-slots`). The twelve that actually block loading are `cordis`, `dsh-attachment`, `dsh-brand`, `dsh-client-ui-conversation`, `dsh-client-ui-renderer`, `dsh-credentials`, `dsh-fs`, `dsh-launch-environment`, `dsh-llm`, `dsh-timeout`, `dsh-typert-protocol`, and `dsh-typert-registry`. `dsh-llm` is the heaviest coupling — more than twenty imports across the source.
165
- - **Declared range ≠ verified range**: `0.1.7-alpha.1` and `alpha.2` fall inside the declaration but were never verified here. What was verified is `0.1.7-rc.1`, `0.1.7-rc.2` (daily use), and `0.2.0-rc.1` (the dev-dependency baseline: gate verdict + typecheck + full suite).
165
+ - **Declared range ≠ verified range**: `0.1.7-alpha.1` and `alpha.2` fall inside the declaration but were never verified here. What was verified is `0.1.7-rc.1`, `0.1.7-rc.2` (daily use), `0.2.0-rc.1` (the dev-dependency baseline: gate verdict + typecheck + full suite), and `0.2.0-rc.2` (dev-dependency baseline + `prepareCall` generation freeze + pi-ai delta-parse patch port).
166
166
  - **The upper bound is a tracking line**: `<0.3.0` means that the moment DSH ships `0.3.0`, this plugin must ship a new release in the same window or every user loses the plugin. The current range spans both `0.1.7` and `0.2.0` (`0.1.8` and `0.1.9` were never published, hence two segments). After changing a range, `npm test` is the verification (local mock gateway, no network, no tokens) — ranges follow what the interfaces declare, and are never "measured" with live probes.
167
167
  - **Peer coverage is now guarded both ways**: `dsh-typert-registry`, `dsh-client-ui-conversation`, and `dsh-client-ui-renderer` were imported by the source but absent from `peerDependencies`, invisible to the gate; they are declared now, and `tests/peer-coverage.spec.ts` asserts both directions — anything the source imports must be declared, and anything declared but unreached must be removed (`dsh-settings` went that way: the settings form is actually provided by `dsh-client-ui-settings`).
168
168
  - **Exemptions are per profile**: only a profile that ran `dsh plugin allow-version` has one, and no record means the plugin must stay inside the declared range. `dsh plugin version-exemptions` lists a profile's exemptions.
package/README.md CHANGED
@@ -162,7 +162,7 @@ API Key 通过 Harness 凭证库提供(引用名 `OPENCODE_GO_API_KEY`),
162
162
  维护时需要注意:
163
163
 
164
164
  - **必选与可选之分**:18 个 peer(17 个 `dsh-*` 加框架 `cordis`)中 6 个标了 `optional`(`dsh-api-remotes`、`dsh-client-locale`、`dsh-client-store`、`dsh-client-ui-model-selection`、`dsh-client-ui-settings`、`dsh-client-ui-slots`);真正卡住加载的是 12 个——`cordis`、`dsh-attachment`、`dsh-brand`、`dsh-client-ui-conversation`、`dsh-client-ui-renderer`、`dsh-credentials`、`dsh-fs`、`dsh-launch-environment`、`dsh-llm`、`dsh-timeout`、`dsh-typert-protocol`、`dsh-typert-registry`。其中 `dsh-llm` 是最重的一处耦合(源码 import 二十余处)。
165
- - **名义范围 ≠ 实测范围**:`0.1.7-alpha.1`、`alpha.2` 落在声明范围内,但本项目没有验证过;实际验证过的是 `0.1.7-rc.1`、`0.1.7-rc.2`(日常使用)与 `0.2.0-rc.1`(开发依赖基线:门禁判定 + typecheck + 全量用例)。
165
+ - **名义范围 ≠ 实测范围**:`0.1.7-alpha.1`、`alpha.2` 落在声明范围内,但本项目没有验证过;实际验证过的是 `0.1.7-rc.1`、`0.1.7-rc.2`(日常使用)、`0.2.0-rc.1`(开发依赖基线:门禁判定 + typecheck + 全量用例)与 `0.2.0-rc.2`(开发依赖基线 + `prepareCall` 代次冻结 + pi-ai 增量解析补丁移植)。
166
166
  - **上界就是跟版线**:`<0.3.0` 意味着 DSH 一旦发布 `0.3.0`,本插件必须同批发新版,否则所有用户加载失败。当前范围跨 `0.1.7` 与 `0.2.0` 两代(`0.1.8`、`0.1.9` 从未发布,所以写成两段而不是一条)。调整范围后用 `npm test` 验证即可(本地 mock 网关,零网络零 token)——范围以接口声明为准,不要用线上探测来"测"出一个范围。
167
167
  - **peer 覆盖已双向守住**:`dsh-typert-registry`、`dsh-client-ui-conversation`、`dsh-client-ui-renderer` 曾被源码 import 却未声明、门禁管不到,现已补进 `peerDependencies`;`tests/peer-coverage.spec.ts` 双向断言——源码用到的必须声明,声明了却没人用的必须删(`dsh-settings` 就这样被移除:设置表单实际由 `dsh-client-ui-settings` 提供)。
168
168
  - **豁免是按 profile 记的**:只有显式执行过 `dsh plugin allow-version` 的 profile 才享有豁免;没有记录就代表必须落在声明范围内。用 `dsh plugin version-exemptions` 可查看当前 profile 的豁免。
package/lib/client.js CHANGED
@@ -462,7 +462,7 @@ if (!document.querySelector("style[data-plugin-css=" + JSON.stringify(id) + "]")
462
462
  style.textContent = ".d7lz0W_root{color:var(--dsw-alias-label-primary);flex-direction:column;gap:1.25rem;display:flex}.d7lz0W_title{margin:0;font-size:1.05rem}.d7lz0W_hint{color:var(--dsw-alias-label-secondary);margin:0;font-size:.8rem}.d7lz0W_warn{color:var(--dsw-alias-state-warn-primary);margin:0;font-size:.8rem}.d7lz0W_ok{color:var(--dsw-alias-state-success-primary);font-size:.8rem}.d7lz0W_block{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:.6rem;flex-direction:column;gap:.5rem;padding:.85rem;display:flex}.d7lz0W_row{flex-wrap:wrap;align-items:center;gap:.5rem;display:flex}.d7lz0W_row>strong{margin-right:auto}.d7lz0W_input{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);min-width:10rem;color:var(--dsw-alias-label-primary);font:inherit;border-radius:.35rem;flex:14rem;padding:.35rem .5rem;font-size:.85rem}.d7lz0W_button{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;border-radius:.35rem;padding:.35rem .7rem;font-size:.8rem}.d7lz0W_button:disabled{color:var(--dsw-alias-state-idle-primary);cursor:default}.d7lz0W_number{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:5rem;color:var(--dsw-alias-label-primary);font:inherit;border-radius:.35rem;padding:.25rem .4rem;font-size:.8rem}.d7lz0W_select{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:auto;max-width:100%;color:var(--dsw-alias-label-primary);font:inherit;border-radius:.35rem;padding:.25rem .4rem;font-size:.8rem}.d7lz0W_list{flex-direction:column;display:flex}.d7lz0W_item{border-top:1px solid var(--dsw-alias-border-l1);align-items:flex-start;gap:.5rem;padding:.45rem .15rem;display:flex}.d7lz0W_item input[type=checkbox]{accent-color:var(--dsw-alias-brand-primary);margin-top:.15rem}.d7lz0W_itemBody{flex-direction:column;gap:.15rem;min-width:0;display:flex}.d7lz0W_itemMain{flex-wrap:wrap;align-items:baseline;gap:.6rem;display:flex}.d7lz0W_itemMeta{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:.75rem;font-size:.75rem;display:flex}.d7lz0W_itemModalities{color:var(--dsw-alias-label-secondary);font-size:.75rem}.d7lz0W_name{color:var(--dsw-alias-label-primary)}.d7lz0W_mono{color:var(--dsw-alias-label-secondary);font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.d7lz0W_badge{color:var(--dsw-alias-brand-primary)}";
463
463
  document.head.appendChild(style);
464
464
  }
465
- var section_default = { "row": "d7lz0W_row", "item": "d7lz0W_item", "input": "d7lz0W_input", "name": "d7lz0W_name", "hint": "d7lz0W_hint", "select": "d7lz0W_select", "list": "d7lz0W_list", "itemBody": "d7lz0W_itemBody", "itemMeta": "d7lz0W_itemMeta", "button": "d7lz0W_button", "ok": "d7lz0W_ok", "block": "d7lz0W_block", "number": "d7lz0W_number", "itemModalities": "d7lz0W_itemModalities", "itemMain": "d7lz0W_itemMain", "root": "d7lz0W_root", "badge": "d7lz0W_badge", "mono": "d7lz0W_mono", "title": "d7lz0W_title", "warn": "d7lz0W_warn" };
465
+ var section_default = { "ok": "d7lz0W_ok", "itemModalities": "d7lz0W_itemModalities", "number": "d7lz0W_number", "hint": "d7lz0W_hint", "item": "d7lz0W_item", "block": "d7lz0W_block", "name": "d7lz0W_name", "warn": "d7lz0W_warn", "itemMain": "d7lz0W_itemMain", "badge": "d7lz0W_badge", "button": "d7lz0W_button", "input": "d7lz0W_input", "row": "d7lz0W_row", "select": "d7lz0W_select", "title": "d7lz0W_title", "list": "d7lz0W_list", "root": "d7lz0W_root", "itemMeta": "d7lz0W_itemMeta", "itemBody": "d7lz0W_itemBody", "mono": "d7lz0W_mono" };
466
466
 
467
467
  // src/client/Section.tsx
468
468
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -963,7 +963,7 @@ if (!document.querySelector("style[data-plugin-css=" + JSON.stringify(id2) + "]"
963
963
  style.textContent = ".mMNkkW_root{align-items:center;display:inline-flex;position:relative}.mMNkkW_trigger{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;white-space:nowrap;border-radius:999px;padding:.35rem .6rem;font-size:.8rem;line-height:1}.mMNkkW_trigger:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l2)}.mMNkkW_panel{z-index:20;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-overlay);width:18rem;color:var(--dsw-alias-label-primary);border-radius:.6rem;flex-direction:column;gap:.6rem;padding:.75rem .85rem;display:flex;position:absolute;bottom:calc(100% + .5rem);right:0;box-shadow:0 8px 24px #0000002e}.mMNkkW_window{flex-direction:column;gap:.25rem;display:flex}.mMNkkW_row{justify-content:space-between;gap:.5rem;font-size:.85rem;display:flex}.mMNkkW_hint{color:var(--dsw-alias-label-secondary);margin:0;font-size:.75rem}.mMNkkW_progress{width:100%;height:.35rem;accent-color:var(--dsw-alias-brand-primary)}.mMNkkW_limited{color:var(--dsw-alias-state-warn-primary);font-size:.75rem}.mMNkkW_warning{border:1px solid var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-label-primary);border-radius:.4rem;padding:.4rem .5rem;font-size:.75rem}.mMNkkW_retry{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;border-radius:.35rem;align-self:flex-start;padding:.25rem .5rem;font-size:.75rem}.mMNkkW_local{border-top:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:.2rem;padding-top:.5rem;display:flex}";
964
964
  document.head.appendChild(style);
965
965
  }
966
- var pill_default = { "retry": "mMNkkW_retry", "root": "mMNkkW_root", "progress": "mMNkkW_progress", "window": "mMNkkW_window", "hint": "mMNkkW_hint", "warning": "mMNkkW_warning", "trigger": "mMNkkW_trigger", "limited": "mMNkkW_limited", "panel": "mMNkkW_panel", "local": "mMNkkW_local", "row": "mMNkkW_row" };
966
+ var pill_default = { "hint": "mMNkkW_hint", "warning": "mMNkkW_warning", "trigger": "mMNkkW_trigger", "row": "mMNkkW_row", "retry": "mMNkkW_retry", "root": "mMNkkW_root", "panel": "mMNkkW_panel", "local": "mMNkkW_local", "window": "mMNkkW_window", "limited": "mMNkkW_limited", "progress": "mMNkkW_progress" };
967
967
 
968
968
  // src/client/UsagePill.tsx
969
969
  var import_jsx_runtime2 = require("react/jsx-runtime");
package/lib/index.js CHANGED
@@ -1439,6 +1439,7 @@ var OpencodeGoAdapter = class extends LlmAdapter {
1439
1439
  input: ["text"]
1440
1440
  },
1441
1441
  overrides: config.modelProtocols,
1442
+ ...this.options.readDocument === void 0 ? {} : { readDocument: this.options.readDocument },
1442
1443
  observers: {
1443
1444
  ...this.options.onFallback === void 0 ? {} : { onFallback: this.options.onFallback },
1444
1445
  ...this.options.onUnconfigured === void 0 ? {} : { onUnconfigured: this.options.onUnconfigured }
@@ -1518,14 +1519,28 @@ var OpencodeGoAdapter = class extends LlmAdapter {
1518
1519
  "UNSUPPORTED_REASONING_EFFORT"
1519
1520
  );
1520
1521
  }
1522
+ async prepareCall(_provider, model, _signal) {
1523
+ const config = this.options.config();
1524
+ const snapshot = await this.catalogOf(config).forModel(model);
1525
+ const facts = snapshot.facts.get(model);
1526
+ if (facts === void 0) throw new LlmError8(`opencode-go has no model "${model}"`, "UNKNOWN_MODEL");
1527
+ const prepared = this.modelInfo(withModelLimit(toPiModel(facts, config.baseURL), config.modelLimits));
1528
+ return {
1529
+ model: prepared,
1530
+ stream: (options) => this.streamWithSnapshot(options, config, snapshot)
1531
+ };
1532
+ }
1521
1533
  async *stream(options) {
1534
+ const config = this.options.config();
1535
+ const snapshot = await this.catalogOf(config).forModel(options.model);
1536
+ yield* this.streamWithSnapshot(options, config, snapshot);
1537
+ }
1538
+ async *streamWithSnapshot(options, config, snapshot) {
1522
1539
  var _stack = [];
1523
1540
  try {
1524
1541
  if (options.stop !== void 0) {
1525
1542
  throw new LlmError8("dshopencodego does not support GenerateOptions.stop", "UNSUPPORTED_OPTION");
1526
1543
  }
1527
- const config = this.options.config();
1528
- const snapshot = await this.catalogOf(config).forModel(options.model);
1529
1544
  const facts = snapshot.facts.get(options.model);
1530
1545
  if (facts === void 0) throw new LlmError8(`opencode-go has no model "${options.model}"`, "UNKNOWN_MODEL");
1531
1546
  const model = withModelLimit(toPiModel(facts, config.baseURL), config.modelLimits);
@@ -13,9 +13,10 @@
13
13
  * @module @dan-ai-studio/dshopencodego/adapter
14
14
  */
15
15
  import { attributionHeaders, LlmAdapter } from '@deepseek-ai/dsh-llm';
16
- import type { GenerateOptions, ImageAttachmentAccess, LlmModelInfo, LlmResolvedModelInfo, ResolvedRetryPolicy, StreamChunk, TokenUsage } from '@deepseek-ai/dsh-llm';
16
+ import type { GenerateOptions, ImageAttachmentAccess, LlmModelInfo, LlmResolvedModelInfo, PreparedAdapterCall, ResolvedRetryPolicy, StreamChunk, TokenUsage } from '@deepseek-ai/dsh-llm';
17
17
  import type { AttachmentStore, ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';
18
18
  import { OpencodeGoCatalog } from './catalog/index.ts';
19
+ import type { GoDoc } from './catalog/go-doc.ts';
19
20
  import type { OpencodeGoConfig } from './config.ts';
20
21
  /** Image machinery the adapter reads once per request. */
21
22
  export interface OpencodeGoImageAccess {
@@ -45,6 +46,11 @@ export interface OpencodeGoAdapterOptions {
45
46
  }[]) => void;
46
47
  /** Observe assistant history degrading to provider-neutral conversion. */
47
48
  readonly onReplayDegrade?: (reason: string) => void;
49
+ /**
50
+ * Read the provider documentation. Defaults to the real fetch; tests inject
51
+ * a fixed document so the suite stays offline. Production omits this.
52
+ */
53
+ readonly readDocument?: () => Promise<GoDoc>;
48
54
  /**
49
55
  * Observe the provider's own usage for one completed call. This is the only
50
56
  * honest source of token counts: the gateway's `/usage` endpoint reports
@@ -86,7 +92,9 @@ export declare class OpencodeGoAdapter extends LlmAdapter {
86
92
  providerRetryPolicy(_provider: string): ResolvedRetryPolicy | undefined;
87
93
  /** Validate an explicit effort against the model's own levels, without clamping. */
88
94
  private resolveReasoningLevel;
95
+ prepareCall(_provider: string, model: string, _signal?: AbortSignal): Promise<PreparedAdapterCall>;
89
96
  stream(options: GenerateOptions): AsyncIterable<StreamChunk>;
97
+ private streamWithSnapshot;
90
98
  }
91
99
  /** Re-exported so a composition can assert the attribution contract in one place. */
92
100
  export { attributionHeaders };
@@ -119,6 +119,7 @@ export class OpencodeGoAdapter extends LlmAdapter {
119
119
  input: ['text'],
120
120
  },
121
121
  overrides: config.modelProtocols,
122
+ ...this.options.readDocument === undefined ? {} : { readDocument: this.options.readDocument },
122
123
  observers: {
123
124
  ...this.options.onFallback === undefined ? {} : { onFallback: this.options.onFallback },
124
125
  ...this.options.onUnconfigured === undefined ? {} : { onUnconfigured: this.options.onUnconfigured },
@@ -213,14 +214,33 @@ export class OpencodeGoAdapter extends LlmAdapter {
213
214
  return effort;
214
215
  throw new LlmError(`opencode-go model "${model.id}" does not support reasoning effort "${effort}"`, 'UNSUPPORTED_REASONING_EFFORT');
215
216
  }
217
+ async prepareCall(_provider, model, _signal) {
218
+ // Freeze one generation: the config, catalog snapshot, and model facts are
219
+ // captured before the first await, so a settings change between preparation
220
+ // and dispatch cannot combine one generation's capabilities with another's
221
+ // endpoint. Mirrors llm-pi-ai's snapshot discipline.
222
+ const config = this.options.config();
223
+ const snapshot = await this.catalogOf(config).forModel(model);
224
+ const facts = snapshot.facts.get(model);
225
+ if (facts === undefined)
226
+ throw new LlmError(`opencode-go has no model "${model}"`, 'UNKNOWN_MODEL');
227
+ const prepared = this.modelInfo(withModelLimit(toPiModel(facts, config.baseURL), config.modelLimits));
228
+ return {
229
+ model: prepared,
230
+ stream: options => this.streamWithSnapshot(options, config, snapshot),
231
+ };
232
+ }
216
233
  async *stream(options) {
234
+ const config = this.options.config();
235
+ const snapshot = await this.catalogOf(config).forModel(options.model);
236
+ yield* this.streamWithSnapshot(options, config, snapshot);
237
+ }
238
+ async *streamWithSnapshot(options, config, snapshot) {
217
239
  const env_1 = { stack: [], error: void 0, hasError: false };
218
240
  try {
219
241
  if (options.stop !== undefined) {
220
242
  throw new LlmError('dshopencodego does not support GenerateOptions.stop', 'UNSUPPORTED_OPTION');
221
243
  }
222
- const config = this.options.config();
223
- const snapshot = await this.catalogOf(config).forModel(options.model);
224
244
  const facts = snapshot.facts.get(options.model);
225
245
  if (facts === undefined)
226
246
  throw new LlmError(`opencode-go has no model "${options.model}"`, 'UNKNOWN_MODEL');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dan-ai-studio/dshopencodego",
3
- "version": "0.1.17",
3
+ "version": "0.1.18",
4
4
  "description": "OpenCode Go provider for DeepSeek Harness: live gateway catalog, per-conversation session header, usage",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -59,6 +59,7 @@
59
59
  "test": "vitest run",
60
60
  "test:coverage": "vitest run --coverage",
61
61
  "test:watch": "vitest",
62
+ "postinstall": "node scripts/patch-pi-ai.mjs",
62
63
  "prepare": "npm run build",
63
64
  "prepack": "npm run build"
64
65
  },
@@ -108,28 +109,28 @@
108
109
  },
109
110
  "devDependencies": {
110
111
  "@deepseek-ai/cordis": "4.0.4",
111
- "@deepseek-ai/dsh-api-remotes": "0.2.0-rc.1",
112
- "@deepseek-ai/dsh-attachment": "0.2.0-rc.1",
113
- "@deepseek-ai/dsh-brand": "0.2.0-rc.1",
114
- "@deepseek-ai/dsh-client-locale": "0.2.0-rc.1",
115
- "@deepseek-ai/dsh-client-store": "0.2.0-rc.1",
116
- "@deepseek-ai/dsh-client-ui-conversation": "^0.2.0-rc.1",
117
- "@deepseek-ai/dsh-client-ui-model-selection": "0.2.0-rc.1",
118
- "@deepseek-ai/dsh-client-ui-renderer": "^0.2.0-rc.1",
119
- "@deepseek-ai/dsh-client-ui-settings": "0.2.0-rc.1",
120
- "@deepseek-ai/dsh-client-ui-slots": "0.2.0-rc.1",
121
- "@deepseek-ai/dsh-credentials": "0.2.0-rc.1",
122
- "@deepseek-ai/dsh-fs": "0.2.0-rc.1",
123
- "@deepseek-ai/dsh-invariants": "0.2.0-rc.1",
124
- "@deepseek-ai/dsh-launch-environment": "0.2.0-rc.1",
125
- "@deepseek-ai/dsh-llm": "0.2.0-rc.1",
126
- "@deepseek-ai/dsh-sandbox": "0.2.0-rc.1",
127
- "@deepseek-ai/dsh-scope": "0.2.0-rc.1",
128
- "@deepseek-ai/dsh-session": "0.2.0-rc.1",
129
- "@deepseek-ai/dsh-settings": "0.2.0-rc.1",
130
- "@deepseek-ai/dsh-timeout": "0.2.0-rc.1",
131
- "@deepseek-ai/dsh-typert-protocol": "0.2.0-rc.1",
132
- "@deepseek-ai/dsh-typert-registry": "^0.2.0-rc.1",
112
+ "@deepseek-ai/dsh-api-remotes": "0.2.0-rc.2",
113
+ "@deepseek-ai/dsh-attachment": "0.2.0-rc.2",
114
+ "@deepseek-ai/dsh-brand": "0.2.0-rc.2",
115
+ "@deepseek-ai/dsh-client-locale": "0.2.0-rc.2",
116
+ "@deepseek-ai/dsh-client-store": "0.2.0-rc.2",
117
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.2.0-rc.2",
118
+ "@deepseek-ai/dsh-client-ui-model-selection": "0.2.0-rc.2",
119
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.2.0-rc.2",
120
+ "@deepseek-ai/dsh-client-ui-settings": "0.2.0-rc.2",
121
+ "@deepseek-ai/dsh-client-ui-slots": "0.2.0-rc.2",
122
+ "@deepseek-ai/dsh-credentials": "0.2.0-rc.2",
123
+ "@deepseek-ai/dsh-fs": "0.2.0-rc.2",
124
+ "@deepseek-ai/dsh-invariants": "0.2.0-rc.2",
125
+ "@deepseek-ai/dsh-launch-environment": "0.2.0-rc.2",
126
+ "@deepseek-ai/dsh-llm": "0.2.0-rc.2",
127
+ "@deepseek-ai/dsh-sandbox": "0.2.0-rc.2",
128
+ "@deepseek-ai/dsh-scope": "0.2.0-rc.2",
129
+ "@deepseek-ai/dsh-session": "0.2.0-rc.2",
130
+ "@deepseek-ai/dsh-settings": "0.2.0-rc.2",
131
+ "@deepseek-ai/dsh-timeout": "0.2.0-rc.2",
132
+ "@deepseek-ai/dsh-typert-protocol": "0.2.0-rc.2",
133
+ "@deepseek-ai/dsh-typert-registry": "^0.2.0-rc.2",
133
134
  "@testing-library/dom": "^10.4.1",
134
135
  "@testing-library/react": "^16.3.0",
135
136
  "@types/node": "^22.20.0",