dsh-web-search-enhanced 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,7 +9,7 @@ row `web-search-enhanced` and selects its provider in the shared `web` row.
9
9
  | Row id | `web-search-enhanced` |
10
10
  | Provider id in `ctx.web` | `search-enhanced` |
11
11
  | Model surface | DSH's own `web_search` (tool-web), unchanged; with the row's Enhanced tools switch on, also `web_search_enhanced` and `list_web_search_providers` |
12
- | Per conversation | one connection or Off, from the composer menu or `/setup-search` |
12
+ | Per conversation | one connection or Off, from the composer menu or the Host command `/setup-search` (Web GUI and dsh-TUI) |
13
13
  | Settings | row settings page on the Plugins page (`plugins.row.config`) |
14
14
 
15
15
  ## What it does
@@ -30,6 +30,13 @@ only their error messages are restated.
30
30
  queries go to it. DeepSeek Messages (the default) and the conversation model
31
31
  stay on; custom connections are on when created. When every remote service
32
32
  is off, the composer menu says more services can be turned on in settings.
33
+ - **`/setup-search`.** A Host command, so it works in the Web GUI and in
34
+ dsh-TUI. `off`, a connection id or `freshness auto|fresh|realtime` change
35
+ the choice from the next model request; dsh-TUI completes these arguments.
36
+ Without arguments the Web GUI opens the chooser, and dsh-TUI prints the
37
+ current choice, routing and the enabled connections (0.16.1 shows only the
38
+ start of that, as a one-line notice). Its description and output are
39
+ English.
33
40
  - **Enhanced tools (optional).** With the row's Enhanced tools switch on (off
34
41
  by default; turning it on agrees that the query goes to the service the
35
42
  Agent picks), the Agent also gets `web_search_enhanced` (`queries` plus a
package/lib/client.cjs CHANGED
@@ -37,7 +37,8 @@ window.__ModuleLoader__.load({
37
37
  tools: {
38
38
  action: "web_search_enhanced",
39
39
  list: "list_web_search_providers"
40
- }
40
+ },
41
+ command: "setup-search"
41
42
  };
42
43
  /**
43
44
  * Key of a row's configuration page on the Plugins page (`plugins.row.config`).
@@ -1520,7 +1521,11 @@ window.__ModuleLoader__.load({
1520
1521
  if (id.startsWith("connection:") && id.length > 11) return { connectionId: id.slice(11) };
1521
1522
  return parseOptions?.(id);
1522
1523
  }
1523
- /** A keyboard entry to the same per-session store the composer menu uses. */
1524
+ /**
1525
+ * The browser's bare invocation of the capability's Host command: a popup over
1526
+ * the same per-session store the composer menu uses. The Host command keeps its
1527
+ * menu row and runs every line with arguments.
1528
+ */
1524
1529
  function selectionCommand(selections, spec) {
1525
1530
  const t = (key) => spec.t(spec.keys[key]);
1526
1531
  const read = async (sessionId) => {
@@ -1530,9 +1535,6 @@ window.__ModuleLoader__.load({
1530
1535
  };
1531
1536
  return {
1532
1537
  name: spec.name,
1533
- label: () => t("label"),
1534
- description: () => t("description"),
1535
- icon: spec.icon,
1536
1538
  available: () => true,
1537
1539
  ui: {
1538
1540
  kind: "popupSelect",
@@ -1580,6 +1582,19 @@ window.__ModuleLoader__.load({
1580
1582
  }
1581
1583
  };
1582
1584
  }
1585
+ /**
1586
+ * Call `ran` after this browser ran the Host command `name` in a Session. A line
1587
+ * with arguments (`/setup-search off`) writes on the Host without the selection
1588
+ * store, so that Session's views must read again. DSH reports each Host command
1589
+ * this browser executed with `command/executed`, without its arguments, so every
1590
+ * run counts; runs from another browser or the TUI are not reported here.
1591
+ * @returns the listener's disposer; it also ends with `ctx`'s fiber.
1592
+ */
1593
+ function followHostCommand(ctx, name, ran) {
1594
+ return ctx.on("command/executed", (sessionId, executed) => {
1595
+ if (executed === name) ran(sessionId);
1596
+ });
1597
+ }
1583
1598
  //#endregion
1584
1599
  //#region ../core/src/client/selection.ts
1585
1600
  var ConnectionSelectionStore = class {
@@ -1660,10 +1675,16 @@ window.__ModuleLoader__.load({
1660
1675
  * read again, the others read on their next load.
1661
1676
  */
1662
1677
  invalidate() {
1663
- for (const entry of this.entries.values()) {
1664
- this.outdate(entry);
1665
- if (entry.observers > 0) this.read(entry);
1666
- }
1678
+ for (const entry of this.entries.values()) this.reread(entry);
1679
+ }
1680
+ /**
1681
+ * The Session's selection changed without this store (its Host command ran):
1682
+ * its views read again, at once when observed, otherwise on their next load.
1683
+ * A read already in flight reads once more.
1684
+ */
1685
+ invalidateSession(sessionId) {
1686
+ const entry = this.entries.get(sessionId);
1687
+ if (entry !== void 0) this.reread(entry);
1667
1688
  }
1668
1689
  entry(sessionId) {
1669
1690
  const existing = this.entries.get(sessionId);
@@ -1696,6 +1717,10 @@ window.__ModuleLoader__.load({
1696
1717
  this.entries.set(sessionId, entry);
1697
1718
  return entry;
1698
1719
  }
1720
+ reread(entry) {
1721
+ this.outdate(entry);
1722
+ if (entry.observers > 0) this.read(entry);
1723
+ }
1699
1724
  outdate(entry) {
1700
1725
  entry.stale = true;
1701
1726
  entry.epoch += 1;
@@ -4277,7 +4302,7 @@ window.__ModuleLoader__.load({
4277
4302
  }
4278
4303
  //#endregion
4279
4304
  //#region src/client/command.ts
4280
- const SEARCH_COMMAND = "setup-search";
4305
+ const SEARCH_COMMAND = SEARCH.command;
4281
4306
  const FRESHNESS_PREFIX = "freshness:";
4282
4307
  const parseFreshness = (id) => {
4283
4308
  const freshness = FRESHNESS.find((mode) => id === FRESHNESS_PREFIX + mode);
@@ -4286,11 +4311,8 @@ window.__ModuleLoader__.load({
4286
4311
  function searchCommand(selections, t) {
4287
4312
  return selectionCommand(selections, {
4288
4313
  name: SEARCH_COMMAND,
4289
- icon: _deepseek_ai_dsh_client_ui_primitives.IconGlobeOutlineRegular,
4290
4314
  t,
4291
4315
  keys: {
4292
- label: "command.label",
4293
- description: "command.description",
4294
4316
  placeholder: "command.placeholder",
4295
4317
  empty: "command.empty",
4296
4318
  noResults: "command.noResults",
@@ -4558,7 +4580,7 @@ window.__ModuleLoader__.load({
4558
4580
  "status.modelReady": "{access} · model search · sent to {name}",
4559
4581
  "status.sessionModelNeedsKey": "The conversation model's API key isn't set",
4560
4582
  "status.sessionModelNeedsSignIn": "Sign in to the DeepSeek account again",
4561
- "status.reason.no-model": "No model chosen for this conversation yet",
4583
+ "status.reason.no-model": "The model for this conversation's next request isn't known yet",
4562
4584
  "status.reason.unknown-route": "Can't read the settings of this model's provider",
4563
4585
  "status.reason.protocol": "Its route declares no supported api",
4564
4586
  "status.reason.endpoint": "Its route has no fixed endpoint",
@@ -4819,7 +4841,7 @@ window.__ModuleLoader__.load({
4819
4841
  "status.modelReady": "{access} · 模型搜索 · 查询发送给 {name}",
4820
4842
  "status.sessionModelNeedsKey": "会话模型的 API Key 未设置",
4821
4843
  "status.sessionModelNeedsSignIn": "请重新登录 DeepSeek 账号",
4822
- "status.reason.no-model": "本会话还没有选择模型",
4844
+ "status.reason.no-model": "还不知道本会话下一次请求用哪个模型",
4823
4845
  "status.reason.unknown-route": "无法读取会话模型服务商的设置",
4824
4846
  "status.reason.protocol": "该路由在模型设置里没有声明支持的 api",
4825
4847
  "status.reason.endpoint": "该路由在模型设置里没有固定的接口地址",
@@ -4903,11 +4925,11 @@ window.__ModuleLoader__.load({
4903
4925
  document.head.appendChild(style);
4904
4926
  }
4905
4927
  var Section_module_css_default = {
4906
- "caption": "La6KHG_caption",
4907
4928
  "container": "La6KHG_container",
4908
- "segmented": "La6KHG_segmented",
4929
+ "label": "La6KHG_label",
4930
+ "caption": "La6KHG_caption",
4909
4931
  "error": "La6KHG_error",
4910
- "label": "La6KHG_label"
4932
+ "segmented": "La6KHG_segmented"
4911
4933
  };
4912
4934
  //#endregion
4913
4935
  //#region src/client/section.ts
@@ -4974,73 +4996,73 @@ window.__ModuleLoader__.load({
4974
4996
  document.head.appendChild(style);
4975
4997
  }
4976
4998
  var Settings_module_css_default = {
4977
- "optionGroup": "o9fCSq_optionGroup",
4978
- "selectCompact": "o9fCSq_selectCompact",
4979
- "hint": "o9fCSq_hint",
4980
- "actions": "o9fCSq_actions",
4981
- "editorTitle": "o9fCSq_editorTitle",
4982
- "section": "o9fCSq_section",
4983
- "prefix": "o9fCSq_prefix",
4984
- "error": "o9fCSq_error",
4985
- "disclosure": "o9fCSq_disclosure",
4986
- "fieldHead": "o9fCSq_fieldHead",
4987
- "page": "o9fCSq_page",
4988
- "rowActions": "o9fCSq_rowActions",
4989
- "segmented": "o9fCSq_segmented",
4990
- "settingLead": "o9fCSq_settingLead",
4991
- "optionGroupTitle": "o9fCSq_optionGroupTitle",
4992
- "rowTitle": "o9fCSq_rowTitle",
4993
- "formField": "o9fCSq_formField",
4994
4999
  "intro": "o9fCSq_intro",
4995
- "settingText": "o9fCSq_settingText",
4996
- "prefixedDisabled": "o9fCSq_prefixedDisabled",
4997
- "settingControl": "o9fCSq_settingControl",
5000
+ "disclosureOpen": "o9fCSq_disclosureOpen",
5001
+ "optionGroup": "o9fCSq_optionGroup",
4998
5002
  "trustCheck": "o9fCSq_trustCheck",
4999
- "prefixed": "o9fCSq_prefixed",
5003
+ "trust": "o9fCSq_trust",
5004
+ "field": "o9fCSq_field",
5005
+ "optionKey": "o9fCSq_optionKey",
5006
+ "success": "o9fCSq_success",
5000
5007
  "sectionHead": "o9fCSq_sectionHead",
5001
- "select": "o9fCSq_select",
5002
- "fieldError": "o9fCSq_fieldError",
5008
+ "confirmText": "o9fCSq_confirmText",
5009
+ "confirmRow": "o9fCSq_confirmRow",
5003
5010
  "inline": "o9fCSq_inline",
5004
- "link": "o9fCSq_link",
5005
- "field": "o9fCSq_field",
5006
- "option": "o9fCSq_option",
5011
+ "prefixedInput": "o9fCSq_prefixedInput",
5012
+ "rowTitle": "o9fCSq_rowTitle",
5013
+ "rowMain": "o9fCSq_rowMain",
5014
+ "rowActions": "o9fCSq_rowActions",
5015
+ "page": "o9fCSq_page",
5016
+ "selectValue": "o9fCSq_selectValue",
5017
+ "prefixedDisabled": "o9fCSq_prefixedDisabled",
5018
+ "rowMeta": "o9fCSq_rowMeta",
5019
+ "reset": "o9fCSq_reset",
5020
+ "actions": "o9fCSq_actions",
5021
+ "settingControl": "o9fCSq_settingControl",
5022
+ "fieldLabel": "o9fCSq_fieldLabel",
5023
+ "section": "o9fCSq_section",
5024
+ "formGrid": "o9fCSq_formGrid",
5025
+ "formWide": "o9fCSq_formWide",
5026
+ "selectCompact": "o9fCSq_selectCompact",
5007
5027
  "textarea": "o9fCSq_textarea",
5028
+ "prefix": "o9fCSq_prefix",
5029
+ "fieldError": "o9fCSq_fieldError",
5008
5030
  "sectionActions": "o9fCSq_sectionActions",
5031
+ "optionName": "o9fCSq_optionName",
5032
+ "row": "o9fCSq_row",
5033
+ "editorTitle": "o9fCSq_editorTitle",
5034
+ "optionWide": "o9fCSq_optionWide",
5009
5035
  "sectionTitle": "o9fCSq_sectionTitle",
5010
- "rowMeta": "o9fCSq_rowMeta",
5011
- "empty": "o9fCSq_empty",
5036
+ "fieldHead": "o9fCSq_fieldHead",
5037
+ "optionGrid": "o9fCSq_optionGrid",
5038
+ "input": "o9fCSq_input",
5039
+ "list": "o9fCSq_list",
5040
+ "optionGroupTitle": "o9fCSq_optionGroupTitle",
5012
5041
  "fieldState": "o9fCSq_fieldState",
5013
- "row": "o9fCSq_row",
5042
+ "settingText": "o9fCSq_settingText",
5014
5043
  "note": "o9fCSq_note",
5015
5044
  "settingRow": "o9fCSq_settingRow",
5016
- "selectChevron": "o9fCSq_selectChevron",
5017
- "list": "o9fCSq_list",
5018
- "trust": "o9fCSq_trust",
5019
- "status": "o9fCSq_status",
5020
- "input": "o9fCSq_input",
5021
- "confirmRow": "o9fCSq_confirmRow",
5022
- "fieldLabel": "o9fCSq_fieldLabel",
5045
+ "error": "o9fCSq_error",
5046
+ "rowLine": "o9fCSq_rowLine",
5047
+ "formField": "o9fCSq_formField",
5048
+ "link": "o9fCSq_link",
5023
5049
  "danger": "o9fCSq_danger",
5024
- "formGrid": "o9fCSq_formGrid",
5025
- "selectAnchor": "o9fCSq_selectAnchor",
5026
- "formWide": "o9fCSq_formWide",
5027
- "success": "o9fCSq_success",
5050
+ "select": "o9fCSq_select",
5051
+ "status": "o9fCSq_status",
5028
5052
  "editor": "o9fCSq_editor",
5029
5053
  "panel": "o9fCSq_panel",
5030
- "disclosureOpen": "o9fCSq_disclosureOpen",
5031
- "reset": "o9fCSq_reset",
5032
- "prefixedInput": "o9fCSq_prefixedInput",
5033
- "optionKey": "o9fCSq_optionKey",
5034
- "optionName": "o9fCSq_optionName",
5035
- "selectValue": "o9fCSq_selectValue",
5036
- "rowMain": "o9fCSq_rowMain",
5037
- "confirmText": "o9fCSq_confirmText",
5038
- "optionWide": "o9fCSq_optionWide",
5039
- "warning": "o9fCSq_warning",
5054
+ "selectAnchor": "o9fCSq_selectAnchor",
5055
+ "segmented": "o9fCSq_segmented",
5056
+ "disclosure": "o9fCSq_disclosure",
5057
+ "hint": "o9fCSq_hint",
5058
+ "option": "o9fCSq_option",
5059
+ "selectChevron": "o9fCSq_selectChevron",
5040
5060
  "settingTitle": "o9fCSq_settingTitle",
5041
- "rowLine": "o9fCSq_rowLine",
5042
- "optionGrid": "o9fCSq_optionGrid",
5043
- "disclosureIcon": "o9fCSq_disclosureIcon"
5061
+ "empty": "o9fCSq_empty",
5062
+ "settingLead": "o9fCSq_settingLead",
5063
+ "prefixed": "o9fCSq_prefixed",
5064
+ "disclosureIcon": "o9fCSq_disclosureIcon",
5065
+ "warning": "o9fCSq_warning"
5044
5066
  };
5045
5067
  //#endregion
5046
5068
  //#region src/client/settings/CredentialEditor.tsx
@@ -5777,7 +5799,11 @@ window.__ModuleLoader__.load({
5777
5799
  }, "search: composer section");
5778
5800
  });
5779
5801
  scope.inject(["commandUi"], (command) => {
5780
- command.effect(() => command.commandUi.register(searchCommand(selection, t)), "search: /setup-search");
5802
+ command.effect(() => command.commandUi.decorate(searchCommand(selection, t)), "search: /setup-search");
5803
+ followHostCommand(command, SEARCH.command, (sessionId) => {
5804
+ selection.invalidateSession(sessionId);
5805
+ pairings.invalidate();
5806
+ });
5781
5807
  });
5782
5808
  const invalidate = () => {
5783
5809
  selection.invalidate();