dsh-edge 0.9.0 → 0.10.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.
Files changed (56) hide show
  1. package/THIRD_PARTY_NOTICES.md +1318 -1075
  2. package/dist/assets/index-Df-65__b.js +110 -0
  3. package/dist/assets/index-b24khbeK.css +1 -0
  4. package/dist/assets/langs/{php-DDkx9sim.js → php-DJl5gRdb.js} +2 -2
  5. package/dist/assets/langs/{ruby-DCxyoPen.js → ruby-5eNB0pDK.js} +2 -2
  6. package/dist/assets/vendor-BNsW4eBh.css +1 -0
  7. package/dist/assets/vendor-CCJJTK99.js +411 -0
  8. package/dist/index.html +8 -8
  9. package/dist/plugins/@deepseek-ai/dsh-api-gateway/client.js +1513 -77
  10. package/dist/plugins/@deepseek-ai/dsh-api-remotes/client.js +3608 -757
  11. package/dist/plugins/@deepseek-ai/dsh-api-session-controller/client.js +2777 -0
  12. package/dist/plugins/@deepseek-ai/dsh-api-workspace-controller/client.js +415 -0
  13. package/dist/plugins/@deepseek-ai/dsh-client-connection/client.js +1975 -7466
  14. package/dist/plugins/@deepseek-ai/dsh-client-locale/client.js +225 -76
  15. package/dist/plugins/@deepseek-ai/dsh-client-modules/client.js +67 -15
  16. package/dist/plugins/@deepseek-ai/dsh-client-ui-agent-preset/client.js +270 -460
  17. package/dist/plugins/@deepseek-ai/dsh-client-ui-approval/client.js +292 -0
  18. package/dist/plugins/@deepseek-ai/dsh-client-ui-attachment/client.js +42 -17
  19. package/dist/plugins/@deepseek-ai/dsh-client-ui-brand-official/client.js +7 -9
  20. package/dist/plugins/@deepseek-ai/dsh-client-ui-chat/client.js +8177 -0
  21. package/dist/plugins/@deepseek-ai/dsh-client-ui-commands/client.js +22 -10
  22. package/dist/plugins/@deepseek-ai/dsh-client-ui-conversation/client.js +14950 -8910
  23. package/dist/plugins/@deepseek-ai/dsh-client-ui-deliverables/client.js +161 -137
  24. package/dist/plugins/@deepseek-ai/dsh-client-ui-goal/client.js +6 -7
  25. package/dist/plugins/@deepseek-ai/dsh-client-ui-input-trigger/client.js +268 -40
  26. package/dist/plugins/@deepseek-ai/dsh-client-ui-jobs/client.js +1 -1
  27. package/dist/plugins/@deepseek-ai/dsh-client-ui-layout/client.js +45 -11
  28. package/dist/plugins/@deepseek-ai/dsh-client-ui-message-feedback/client.js +30 -58
  29. package/dist/plugins/@deepseek-ai/dsh-client-ui-model-selection/client.js +188 -89
  30. package/dist/plugins/@deepseek-ai/dsh-client-ui-permission-presets/client.js +105 -75
  31. package/dist/plugins/@deepseek-ai/dsh-client-ui-renderer/client.js +650 -188
  32. package/dist/plugins/@deepseek-ai/dsh-client-ui-schedule/client.js +307 -0
  33. package/dist/plugins/@deepseek-ai/dsh-client-ui-session/client.js +340 -0
  34. package/dist/plugins/@deepseek-ai/dsh-client-ui-settings/client.js +57 -50
  35. package/dist/plugins/@deepseek-ai/dsh-client-ui-settings-general/client.js +134 -69
  36. package/dist/plugins/@deepseek-ai/dsh-client-ui-settings-models/client.js +575 -442
  37. package/dist/plugins/@deepseek-ai/dsh-client-ui-sidebar/client.js +24 -11
  38. package/dist/plugins/@deepseek-ai/dsh-client-ui-skill/client.js +13 -9
  39. package/dist/plugins/@deepseek-ai/dsh-client-ui-subagent/client.js +44 -20
  40. package/dist/plugins/@deepseek-ai/dsh-client-ui-theme/client.js +265 -94
  41. package/dist/plugins/@deepseek-ai/dsh-client-ui-tool/client.js +899 -433
  42. package/dist/plugins/@deepseek-ai/dsh-client-ui-trajectory/client.js +1472 -613
  43. package/dist/plugins/@deepseek-ai/dsh-client-ui-user-questions/client.js +249 -95
  44. package/dist/plugins/@deepseek-ai/dsh-client-ui-workflow-run/client.js +5 -5
  45. package/dist/plugins/@deepseek-ai/dsh-client-ui-workspace/client.js +425 -146
  46. package/dist/plugins/@deepseek-ai/dsh-typert-registry/client.js +29 -14
  47. package/dist/plugins/dsh-edge-client-ui/client.js +28 -26
  48. package/package.json +62 -58
  49. package/scripts/verify-packed.mjs +1 -1
  50. package/worker/direct/index.js +2866 -1466
  51. package/worker/isolated/index.js +2438 -1038
  52. package/dist/assets/index-C6eRlFa6.css +0 -1
  53. package/dist/assets/index-ClqxG24t.js +0 -96
  54. package/dist/assets/vendor-CjyC-hUb.css +0 -1
  55. package/dist/assets/vendor-D22_Mp1f.js +0 -411
  56. package/dist/plugins/@deepseek-ai/dsh-client-runtime/client.js +0 -10574
@@ -5,18 +5,99 @@ window.__ModuleLoader__.load({
5
5
  var exports = module.exports;
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
7
  let _deepseek_ai_cordis = require("@deepseek-ai/cordis");
8
- let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
8
+ let _deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
9
9
  let react_jsx_runtime = require("react/jsx-runtime");
10
10
  let react = require("react");
11
11
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
12
+ //#region lib/types/client/catalog.js
13
+ /** One Host-generation model catalog shared by every Session selector. */
14
+ /** Loads at most one model catalog for the current Host generation. */
15
+ var ModelCatalogDirectory = class {
16
+ ctx;
17
+ /** Current shared catalog value and load lifecycle. */
18
+ store = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)({
19
+ value: null,
20
+ status: "idle",
21
+ error: null
22
+ });
23
+ generation = 0;
24
+ inflight;
25
+ /**
26
+ * @param ctx - the providing plugin's context, whose `remote.session`
27
+ * namespace carries the Host-generation catalog.
28
+ */
29
+ constructor(ctx) {
30
+ this.ctx = ctx;
31
+ }
32
+ /**
33
+ * Return the current generation's catalog, sharing its one in-flight load.
34
+ * @returns the loaded global catalog.
35
+ */
36
+ load() {
37
+ const state = this.store.getSnapshot();
38
+ if (state.status === "ready" && state.value !== null) return Promise.resolve(state.value);
39
+ if (this.inflight !== void 0) return this.inflight;
40
+ const generation = this.generation;
41
+ this.store.update((draft) => {
42
+ draft.status = "loading";
43
+ draft.error = null;
44
+ });
45
+ const operation = this.ctx.remote.session.modelCatalog().then((response) => {
46
+ if (!response.ok) throw new Error(`${response.error.code}: ${response.error.message}`);
47
+ if (generation === this.generation) this.store.set({
48
+ value: response.value,
49
+ status: "ready",
50
+ error: null
51
+ });
52
+ return response.value;
53
+ }).catch((error) => {
54
+ if (generation === this.generation) this.store.update((draft) => {
55
+ draft.status = "error";
56
+ draft.error = error instanceof Error ? error.message : String(error);
57
+ });
58
+ throw error;
59
+ }).finally(() => {
60
+ if (generation === this.generation && this.inflight === operation) this.inflight = void 0;
61
+ });
62
+ this.inflight = operation;
63
+ return operation;
64
+ }
65
+ /**
66
+ * Invalidate the loaded catalog; the next explicit menu read reloads it.
67
+ * @param clear - whether values from the previous Host generation must be hidden.
68
+ */
69
+ invalidate(clear = false) {
70
+ this.generation += 1;
71
+ this.inflight = void 0;
72
+ const value = clear ? null : this.store.getSnapshot().value;
73
+ this.store.set({
74
+ value,
75
+ status: "idle",
76
+ error: null
77
+ });
78
+ }
79
+ /** Invalidate and reload the catalog after a Host-side model input changes. */
80
+ refresh() {
81
+ this.invalidate();
82
+ this.load().catch(() => {});
83
+ }
84
+ /** Clear Host-specific values and load the replacement Host generation. */
85
+ resetGeneration() {
86
+ this.invalidate(true);
87
+ this.load().catch(() => {});
88
+ }
89
+ };
90
+ //#endregion
12
91
  //#region lib/types/client/directory.js
13
92
  /** One session's shared directory controller; disposed with the session scope. */
14
93
  var ModelDirectory = class {
15
94
  sessions;
16
95
  sessionId;
17
96
  available;
97
+ catalog;
98
+ projected;
18
99
  /** The shared snapshot both entries render from (uSES-safe store). */
19
- store = (0, _deepseek_ai_dsh_client_runtime_client.createSnapshotStore)({
100
+ store = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)({
20
101
  current: null,
21
102
  routable: null,
22
103
  groups: [],
@@ -24,58 +105,47 @@ window.__ModuleLoader__.load({
24
105
  status: "idle",
25
106
  error: null
26
107
  });
27
- /** Latest operation wins; an older response never overwrites a newer one. */
108
+ /** Latest selection operation wins; an older response never overwrites a newer one. */
28
109
  generation = 0;
29
110
  disposed = false;
111
+ resolved = false;
112
+ unsubscribeCatalog;
113
+ unsubscribeSelection;
30
114
  /**
31
115
  * @param sessions - the session wire face (captured from the plugin's root connection).
32
116
  * @param sessionId - the owning session.
33
117
  * @param available - whether this session may use Agent-bound model RPCs.
118
+ * @param catalog - Host-generation catalog shared by every Session.
119
+ * @param projected - durable model selection projected from Session history.
34
120
  */
35
- constructor(sessions, sessionId, available) {
121
+ constructor(sessions, sessionId, available, catalog, projected) {
36
122
  this.sessions = sessions;
37
123
  this.sessionId = sessionId;
38
124
  this.available = available;
125
+ this.catalog = catalog;
126
+ this.projected = projected;
127
+ this.unsubscribeCatalog = catalog.store.subscribe(() => {
128
+ this.syncInputs();
129
+ });
130
+ this.unsubscribeSelection = projected.subscribe(() => {
131
+ this.syncInputs();
132
+ });
133
+ this.syncInputs();
39
134
  }
40
135
  /**
41
- * Refresh the advisory directory (both entries call this on open).
42
- * Failure preserves the last good groups and current selection.
136
+ * Ensure the Host generation's shared advisory catalog is loaded.
43
137
  * @returns the fresh directory value.
44
138
  */
45
139
  async load() {
46
140
  this.assertAvailable();
47
- const generation = ++this.generation;
48
- this.store.update((s) => {
49
- s.status = "loading";
50
- s.error = null;
51
- });
52
- const { result } = await this.sessions.models({ sessionId: this.sessionId });
53
- if (this.disposed || generation !== this.generation) {
54
- if (!result.ok) throw new Error(`${result.error.code}: ${result.error.message}`);
55
- return result.value;
56
- }
57
- if (!result.ok) {
58
- this.store.update((s) => {
59
- s.status = "error";
60
- s.error = `${result.error.code}: ${result.error.message}`;
61
- });
62
- throw new Error(`session.models failed: ${result.error.code}: ${result.error.message}`);
63
- }
64
- const { current, routable, groups, failures } = result.value;
65
- this.store.update((s) => {
66
- s.current = current;
67
- s.routable = routable;
68
- s.groups = groups;
69
- s.failures = failures;
70
- s.status = "ready";
71
- s.error = null;
72
- });
73
- return result.value;
141
+ await this.catalog.load();
142
+ this.syncInputs();
143
+ return this.store.getSnapshot();
74
144
  }
75
145
  /**
76
- * Select the complete provider/model/reasoning selection (both entries submit through here). Success
77
- * updates the shared current; failure surfaces on the store and throws so
78
- * each entry's own retry surface engages.
146
+ * Select the complete provider/model/reasoning selection. The durable
147
+ * projection frame updates the shared current; failures surface on the store
148
+ * and throw so each entry's own retry surface engages.
79
149
  * @param selection - provider, provider-owned model id, and optional adapter-owned effort.
80
150
  */
81
151
  async select(selection) {
@@ -85,7 +155,7 @@ window.__ModuleLoader__.load({
85
155
  s.status = "selecting";
86
156
  s.error = null;
87
157
  });
88
- const { result } = await this.sessions.selectModel({
158
+ const result = await this.sessions.selectModel({
89
159
  sessionId: this.sessionId,
90
160
  provider: selection.provider,
91
161
  model: selection.model,
@@ -103,39 +173,69 @@ window.__ModuleLoader__.load({
103
173
  throw new Error(`session.selectModel failed: ${result.error.code}: ${result.error.message}`);
104
174
  }
105
175
  this.store.update((s) => {
106
- s.current = result.value.selected;
107
- s.routable = true;
108
176
  s.status = "ready";
109
177
  s.error = null;
110
178
  });
179
+ this.syncInputs();
111
180
  }
112
181
  /**
113
- * Drop the previous Host generation's projection and repull it. Clearing
114
- * first prevents an unconsumed process-local selection from being displayed
115
- * while the restarted Host has restored the last logged model selection.
182
+ * Invalidate an in-flight selection response from the previous Host generation.
116
183
  */
117
184
  resetConnected() {
118
185
  if (this.disposed) return;
119
186
  ++this.generation;
120
- this.store.update((s) => {
121
- s.current = null;
122
- s.routable = null;
123
- s.groups = [];
124
- s.failures = [];
125
- s.status = "idle";
126
- s.error = null;
187
+ this.store.update((state) => {
188
+ if (state.status === "selecting") state.status = "idle";
189
+ state.error = null;
127
190
  });
128
- if (!this.available()) return;
129
- this.load().catch(() => {});
191
+ this.syncInputs();
130
192
  }
131
193
  /** Scope teardown: late settlements lose write access to the store. */
132
194
  dispose() {
133
195
  this.disposed = true;
196
+ this.unsubscribeSelection();
197
+ this.unsubscribeCatalog();
134
198
  }
135
199
  assertAvailable() {
136
200
  if (!this.available()) throw new Error("model selection is unavailable for addressed subagent sessions");
137
201
  }
202
+ syncInputs() {
203
+ if (this.disposed) return;
204
+ const catalog = this.catalog.store.getSnapshot();
205
+ const projected = modelSelectionProjection(this.projected.getSnapshot());
206
+ if (catalog.status !== "ready" || catalog.value === null || projected === void 0) {
207
+ if (this.resolved) {
208
+ if (catalog.status === "error") this.store.update((state) => {
209
+ state.status = "error";
210
+ state.error = catalog.error;
211
+ });
212
+ return;
213
+ }
214
+ this.store.set({
215
+ current: null,
216
+ routable: null,
217
+ groups: [],
218
+ failures: [],
219
+ status: catalog.status === "error" ? "error" : "loading",
220
+ error: catalog.error
221
+ });
222
+ return;
223
+ }
224
+ const current = projected.next ?? catalog.value.default;
225
+ this.resolved = true;
226
+ this.store.set({
227
+ current,
228
+ routable: catalog.value.routableProviders.includes(current.provider),
229
+ groups: catalog.value.groups,
230
+ failures: catalog.value.failures,
231
+ status: this.store.getSnapshot().status === "selecting" ? "selecting" : "ready",
232
+ error: null
233
+ });
234
+ }
138
235
  };
236
+ function modelSelectionProjection(value) {
237
+ return value === void 0 ? void 0 : value;
238
+ }
139
239
  //#endregion
140
240
  //#region lib/types/client/service.js
141
241
  /**
@@ -155,11 +255,12 @@ window.__ModuleLoader__.load({
155
255
  /** The `ctx.modelDirectories` session model-selection service. */
156
256
  var ModelDirectoryResolver = class extends _deepseek_ai_cordis.Service {
157
257
  static inject = [
158
- "connection",
159
258
  "sessions",
160
- "remote"
259
+ "remote",
260
+ "remote.session"
161
261
  ];
162
262
  live = { directories: /* @__PURE__ */ new Map() };
263
+ catalog;
163
264
  /** Localized composer-block copy; this plugin owns the string it raises. */
164
265
  blockReason;
165
266
  /**
@@ -169,14 +270,21 @@ window.__ModuleLoader__.load({
169
270
  constructor(ctx, config) {
170
271
  super(ctx, "modelDirectories");
171
272
  this.blockReason = config.blockReason;
273
+ this.catalog = new ModelCatalogDirectory(ctx);
274
+ this.catalog.load().catch(() => {});
172
275
  ctx.on("connection/reset", () => {
276
+ this.catalog.resetGeneration();
173
277
  for (const directory of this.live.directories.values()) directory.resetConnected();
174
278
  });
175
- const refresh = () => {
176
- for (const directory of this.live.directories.values()) directory.load().catch(() => void 0);
177
- };
178
- ctx.remote.$on("llm/adapters-updated", refresh);
179
- ctx.remote.$on("settings/document-updated", refresh);
279
+ ctx.remote.$on("llm/adapters-updated", () => {
280
+ this.catalog.refresh();
281
+ });
282
+ ctx.remote.$on("settings/document-updated", () => {
283
+ this.catalog.refresh();
284
+ });
285
+ ctx.remote.$on("credentials/reference-updated", () => {
286
+ this.catalog.refresh();
287
+ });
180
288
  }
181
289
  /**
182
290
  * Resolve the per-session shared directory (lazy; the scope disposer
@@ -188,10 +296,12 @@ window.__ModuleLoader__.load({
188
296
  const { live } = this;
189
297
  const existing = live.directories.get(sessionId);
190
298
  if (existing !== void 0) return existing;
191
- const sessions = this.ctx.get("sessions");
299
+ const sessions = this.ctx.sessions;
192
300
  const actx = sessions.scope(sessionId);
193
301
  if (actx === void 0) throw new Error(`ui-model-selection: session "${String(sessionId)}" resolved no scope`);
194
- const directory = new ModelDirectory(this.ctx.get("connection").api.sessions, sessionId, () => sessions.subagentAddress(sessionId) === void 0);
302
+ const binding = sessions.binding(sessionId);
303
+ if (binding === void 0) throw new Error(`ui-model-selection: session "${String(sessionId)}" resolved no binding`);
304
+ const directory = new ModelDirectory(this.ctx.remote.session, sessionId, () => sessions.subagentAddress(sessionId) === void 0, this.catalog, binding.session.projections.faceOf("modelSelection"));
195
305
  live.directories.set(sessionId, directory);
196
306
  const conversation = this.ctx.get("conversation");
197
307
  if (conversation !== void 0) {
@@ -231,7 +341,7 @@ window.__ModuleLoader__.load({
231
341
  }
232
342
  //#endregion
233
343
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-model-selection/src/client/ModelSelect.module.css.mjs
234
- const css = "._7KE1Ra_root{min-width:0;position:relative}._7KE1Ra_trigger{min-width:0;max-width:min(360px,45cqw);height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:24px;outline:none;align-items:center;gap:4px;padding:0 4px 0 8px;font-size:13px;font-weight:500;line-height:20px;display:flex}._7KE1Ra_trigger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}._7KE1Ra_trigger:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}._7KE1Ra_trigger:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}._7KE1Ra_triggerLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}._7KE1Ra_triggerEffort{color:var(--dsw-alias-label-caption);flex:none}._7KE1Ra_chevron{color:var(--dsw-alias-label-caption);flex:none;transition:transform .12s}._7KE1Ra_chevronOpen{transform:rotate(180deg)}._7KE1Ra_menu{z-index:20;border:1px solid var(--dsw-alias-border-inverted);background:var(--dsw-specific-menu);width:max-content;min-width:min(240px,100vw - 32px);max-width:min(420px,100vw - 32px);max-height:min(360px,100vh - 96px);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px;flex-direction:column;padding:4px;display:flex;position:absolute;bottom:calc(100% + 8px);right:0;overflow:hidden}._7KE1Ra_status,._7KE1Ra_empty{color:var(--dsw-alias-label-tertiary);padding:10px;font-size:13px;line-height:20px}._7KE1Ra_error,._7KE1Ra_warning{background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary);border-radius:8px;justify-content:space-between;align-items:flex-start;gap:8px;margin-bottom:4px;padding:7px 8px;font-size:12px;line-height:18px;display:flex}._7KE1Ra_warning{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-state-warn-label)}._7KE1Ra_retry{color:inherit;font:inherit;cursor:pointer;background:0 0;border:none;flex:none;padding:0;font-weight:600}._7KE1Ra_groups{min-height:0;overflow-y:auto}._7KE1Ra_group+._7KE1Ra_group{margin-top:4px}._7KE1Ra_groupTitle{z-index:1;background:var(--dsw-specific-menu);color:var(--dsw-alias-label-tertiary);padding:5px 8px 3px;font-size:12px;font-weight:500;line-height:18px;position:sticky;top:0}._7KE1Ra_option{box-sizing:border-box;width:auto;min-width:100%;min-height:38px;color:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:10px;outline:none;align-items:center;gap:8px;padding:6px 8px;display:flex}._7KE1Ra_option:hover:not(:disabled),._7KE1Ra_option:focus-visible{background:var(--dsw-alias-interactive-bg-hover)}._7KE1Ra_selected{background:0 0}._7KE1Ra_option:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}._7KE1Ra_optionCopy{flex-direction:column;flex:1;min-width:0;display:flex}._7KE1Ra_modelName{color:inherit;text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:500;line-height:20px;overflow:hidden}._7KE1Ra_description{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:18px;overflow:hidden}._7KE1Ra_check{color:var(--dsw-alias-label-primary);flex:0 0 18px;place-items:center;display:grid}._7KE1Ra_cell{box-sizing:border-box;width:auto;min-width:100%;height:40px;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;background:0 0;border:none;border-radius:10px;align-items:center;gap:8px;padding:0 10px;font-size:14px;line-height:22px;display:flex}._7KE1Ra_cell:hover{background:var(--dsw-alias-interactive-bg-hover)}._7KE1Ra_cellLabel{white-space:nowrap;flex:none}._7KE1Ra_cellValue{text-overflow:ellipsis;white-space:nowrap;text-align:right;min-width:0;color:var(--dsw-alias-label-tertiary);flex:auto;overflow:hidden}._7KE1Ra_cellChevron{color:var(--dsw-alias-label-tertiary);flex:none}";
344
+ const css = "._7KE1Ra_root{min-width:0;position:relative}._7KE1Ra_trigger{min-width:0;max-width:min(360px,45cqw);height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:24px;outline:none;align-items:center;gap:4px;padding:0 4px 0 8px;font-size:13px;font-weight:500;line-height:20px;display:flex}._7KE1Ra_trigger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}._7KE1Ra_trigger:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}._7KE1Ra_trigger:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}._7KE1Ra_triggerLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}._7KE1Ra_triggerEffort{color:var(--dsw-alias-label-caption);flex:none}._7KE1Ra_chevron{color:var(--dsw-alias-label-caption);flex:none;transition:transform .12s}._7KE1Ra_chevronOpen{transform:rotate(180deg)}._7KE1Ra_menu{z-index:20;background:var(--dsw-specific-menu);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);width:max-content;min-width:min(240px,100vw - 32px);max-width:min(420px,100vw - 32px);max-height:min(360px,100vh - 96px);box-shadow:var(--dsw-elevation-prominent);color:var(--dsw-alias-label-primary);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border:0;border-radius:20px;flex-direction:column;padding:4px;display:flex;position:absolute;bottom:calc(100% + 8px);right:0;overflow:hidden}._7KE1Ra_status,._7KE1Ra_empty{color:var(--dsw-alias-label-tertiary);padding:10px;font-size:13px;line-height:20px}._7KE1Ra_error,._7KE1Ra_warning{background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary);border-radius:8px;justify-content:space-between;align-items:flex-start;gap:8px;margin-bottom:4px;padding:7px 8px;font-size:12px;line-height:18px;display:flex}._7KE1Ra_warning{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-state-warn-label)}._7KE1Ra_retry{color:inherit;font:inherit;cursor:pointer;background:0 0;border:none;flex:none;padding:0;font-weight:600}._7KE1Ra_groups{min-height:0;overflow-y:auto}._7KE1Ra_group+._7KE1Ra_group{margin-top:4px}._7KE1Ra_groupTitle{z-index:1;background:var(--dsw-specific-menu);color:var(--dsw-alias-label-tertiary);padding:5px 8px 3px;font-size:12px;font-weight:500;line-height:18px;position:sticky;top:0}._7KE1Ra_option{box-sizing:border-box;width:auto;min-width:100%;min-height:38px;color:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:10px;outline:none;align-items:center;gap:8px;padding:6px 8px;display:flex}._7KE1Ra_option:hover:not(:disabled),._7KE1Ra_option:focus-visible{background:var(--dsw-alias-interactive-bg-hover)}._7KE1Ra_selected{background:0 0}._7KE1Ra_option:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}._7KE1Ra_optionCopy{flex-direction:column;flex:1;min-width:0;display:flex}._7KE1Ra_modelName{color:inherit;text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:500;line-height:20px;overflow:hidden}._7KE1Ra_check{color:var(--dsw-alias-label-primary);flex:0 0 18px;place-items:center;display:grid}._7KE1Ra_cell{box-sizing:border-box;width:auto;min-width:100%;height:40px;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;background:0 0;border:none;border-radius:10px;align-items:center;gap:8px;padding:0 10px;font-size:14px;line-height:22px;display:flex}._7KE1Ra_cell:hover{background:var(--dsw-alias-interactive-bg-hover)}._7KE1Ra_cellLabel{white-space:nowrap;flex:none}._7KE1Ra_cellValue{text-overflow:ellipsis;white-space:nowrap;text-align:right;min-width:0;color:var(--dsw-alias-label-tertiary);flex:auto;overflow:hidden}._7KE1Ra_cellChevron{color:var(--dsw-alias-label-tertiary);flex:none}";
235
345
  const tagId = "@deepseek-ai/dsh-client-ui-model-selection/ModelSelect.module.css";
236
346
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
237
347
  const tag = document.createElement("style");
@@ -248,7 +358,6 @@ window.__ModuleLoader__.load({
248
358
  "check": "_7KE1Ra_check",
249
359
  "chevron": "_7KE1Ra_chevron",
250
360
  "chevronOpen": "_7KE1Ra_chevronOpen",
251
- "description": "_7KE1Ra_description",
252
361
  "empty": "_7KE1Ra_empty",
253
362
  "error": "_7KE1Ra_error",
254
363
  "group": "_7KE1Ra_group",
@@ -319,20 +428,13 @@ window.__ModuleLoader__.load({
319
428
  }] : [], ...reasoning.efforts.map((effort) => ({
320
429
  key: `effort:${effort.id}`,
321
430
  effort: effort.id,
322
- label: effort.name,
323
- ...effort.description === void 0 ? {} : { description: effort.description }
431
+ label: effort.name
324
432
  }))], [reasoning, t]);
325
433
  const busy = state.status === "selecting";
326
434
  const reload = () => {
327
435
  lastActionRef.current = "load";
328
436
  load();
329
437
  };
330
- (0, react.useEffect)(() => {
331
- if (available) {
332
- lastActionRef.current = "load";
333
- load();
334
- }
335
- }, [available, load]);
336
438
  (0, react.useEffect)(() => {
337
439
  if (!open) return;
338
440
  const closeOutside = (event) => {
@@ -415,9 +517,10 @@ window.__ModuleLoader__.load({
415
517
  lastActionRef.current = "select";
416
518
  select(selection).then(settleSelection);
417
519
  };
418
- const modelLabel = currentChoice?.model.name ?? t("trigger.fallback");
520
+ const waiting = state.current === null && state.status === "loading";
521
+ const modelLabel = waiting ? t("trigger.loading") : currentChoice?.model.name ?? (state.current === null ? t("trigger.fallback") : `${state.current.provider}/${state.current.model}`);
419
522
  const triggerLabel = effortLabel === void 0 ? modelLabel : `${modelLabel} · ${effortLabel}`;
420
- const triggerAria = currentChoice === void 0 ? t("trigger.selectAria") : effortLabel === void 0 ? t("trigger.aria", { model: modelLabel }) : t("trigger.ariaEffort", {
523
+ const triggerAria = waiting ? t("trigger.loading") : state.current === null ? t("trigger.selectAria") : effortLabel === void 0 ? t("trigger.aria", { model: modelLabel }) : t("trigger.ariaEffort", {
421
524
  model: modelLabel,
422
525
  effort: effortLabel
423
526
  });
@@ -561,15 +664,12 @@ window.__ModuleLoader__.load({
561
664
  model: model.id
562
665
  });
563
666
  },
564
- children: [(0, react_jsx_runtime.jsxs)("span", {
667
+ children: [(0, react_jsx_runtime.jsx)("span", {
565
668
  className: ModelSelect_module_css_default.optionCopy,
566
- children: [(0, react_jsx_runtime.jsx)("span", {
669
+ children: (0, react_jsx_runtime.jsx)("span", {
567
670
  className: ModelSelect_module_css_default.modelName,
568
671
  children: model.name
569
- }), model.description !== void 0 && (0, react_jsx_runtime.jsx)("span", {
570
- className: ModelSelect_module_css_default.description,
571
- children: model.description
572
- })]
672
+ })
573
673
  }), (0, react_jsx_runtime.jsx)("span", {
574
674
  className: ModelSelect_module_css_default.check,
575
675
  children: selected ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutline16, {}) : null
@@ -605,15 +705,12 @@ window.__ModuleLoader__.load({
605
705
  onClick: () => {
606
706
  chooseEffort(level.effort);
607
707
  },
608
- children: [(0, react_jsx_runtime.jsxs)("span", {
708
+ children: [(0, react_jsx_runtime.jsx)("span", {
609
709
  className: ModelSelect_module_css_default.optionCopy,
610
- children: [(0, react_jsx_runtime.jsx)("span", {
710
+ children: (0, react_jsx_runtime.jsx)("span", {
611
711
  className: ModelSelect_module_css_default.modelName,
612
712
  children: level.label
613
- }), level.description !== void 0 && (0, react_jsx_runtime.jsx)("span", {
614
- className: ModelSelect_module_css_default.description,
615
- children: level.description
616
- })]
713
+ })
617
714
  }), (0, react_jsx_runtime.jsx)("span", {
618
715
  className: ModelSelect_module_css_default.check,
619
716
  children: effectiveEffort === level.effort ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutline16, {}) : null
@@ -637,8 +734,8 @@ window.__ModuleLoader__.load({
637
734
  /**
638
735
  * `model` namespace dictionaries.
639
736
  *
640
- * `trigger.selectAria` reads identically to `trigger.fallback` today and is
641
- * still a separate key: the visible fallback label and the accessible name of
737
+ * `trigger.selectAria` intentionally matches `trigger.fallback` but remains a
738
+ * separate key: the visible fallback label and the accessible name of
642
739
  * an unset trigger are free to diverge per locale, and folding it into
643
740
  * `trigger.aria` would announce the degenerate "Select model, current Select
644
741
  * model".
@@ -648,6 +745,7 @@ window.__ModuleLoader__.load({
648
745
  "command.description": "选择本会话使用的模型",
649
746
  "option.loadError": "目录加载失败:{message}",
650
747
  "trigger.fallback": "选择模型",
748
+ "trigger.loading": "正在加载模型…",
651
749
  "trigger.selectAria": "选择模型",
652
750
  "trigger.aria": "选择模型,当前 {model}",
653
751
  "trigger.ariaEffort": "选择模型,当前 {model},推理等级 {effort}",
@@ -668,6 +766,7 @@ window.__ModuleLoader__.load({
668
766
  "command.description": "Select the model for this conversation",
669
767
  "option.loadError": "Catalog failed to load: {message}",
670
768
  "trigger.fallback": "Select model",
769
+ "trigger.loading": "Loading models…",
671
770
  "trigger.selectAria": "Select model",
672
771
  "trigger.aria": "Select model, current {model}",
673
772
  "trigger.ariaEffort": "Select model, current {model}, reasoning effort {effort}",
@@ -696,7 +795,7 @@ window.__ModuleLoader__.load({
696
795
  id: rowId(group.id, model.id),
697
796
  label: model.name,
698
797
  detail: model.description !== void 0 ? `${group.name} · ${model.description}` : group.name,
699
- ...directory.current.provider === group.id && directory.current.model === model.id ? { active: true } : {}
798
+ ...directory.current !== null && directory.current.provider === group.id && directory.current.model === model.id ? { active: true } : {}
700
799
  });
701
800
  for (const failure of directory.failures) rows.push({
702
801
  id: `failure/${failure.id}`,
@@ -728,11 +827,11 @@ window.__ModuleLoader__.load({
728
827
  /** Required services: the contribution registry, the seat's slot registry, locale, and the service's own faces. */
729
828
  const inject = [
730
829
  "commandUi",
731
- "connection",
732
830
  "locale",
733
831
  "sessions",
734
832
  "slots",
735
- "remote"
833
+ "remote",
834
+ "remote.session"
736
835
  ];
737
836
  /**
738
837
  * Client plugin body: mount ModelDirectoryResolver, register the `model` dictionaries,