dsh-more 0.0.5 → 0.0.6

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 (27) hide show
  1. package/README.md +15 -7
  2. package/README.zh-CN.md +15 -7
  3. package/dist/client.js +810 -291
  4. package/dist/index.js +312 -131
  5. package/dist/types/generated/host-settings-schema.d.ts +4 -2
  6. package/dist/types/generated/patch-catalog.d.ts +12 -4
  7. package/dist/types/patches/model-capabilities/client/api.d.ts +4 -0
  8. package/dist/types/patches/model-capabilities/client/editor.d.ts +26 -0
  9. package/dist/types/patches/model-capabilities/client/index.d.ts +10 -0
  10. package/dist/types/patches/model-capabilities/client/model-entries.d.ts +15 -0
  11. package/dist/types/patches/model-capabilities/client/styles.d.ts +1 -0
  12. package/dist/types/patches/model-capabilities/host/deepseek.d.ts +11 -0
  13. package/dist/types/patches/{model-reasoning-efforts → model-capabilities}/host/validate.d.ts +3 -2
  14. package/dist/types/patches/model-capabilities/shared.d.ts +38 -0
  15. package/dist/types/patches/projectless-tasks/client/adapter.d.ts +15 -0
  16. package/dist/types/patches/projectless-tasks/client/create-task.d.ts +7 -0
  17. package/dist/types/patches/projectless-tasks/client/draft.d.ts +9 -0
  18. package/dist/types/patches/projectless-tasks/client/index.d.ts +2 -0
  19. package/dist/types/patches/projectless-tasks/client/new-session.d.ts +34 -0
  20. package/dist/types/patches/projectless-tasks/client/picker.d.ts +26 -0
  21. package/dist/types/patches/projectless-tasks/host/index.d.ts +5 -0
  22. package/dist/types/patches/projectless-tasks/shared.d.ts +6 -0
  23. package/dsh.plugin.json +1 -1
  24. package/package.json +1 -1
  25. package/dist/types/patches/model-reasoning-efforts/client/index.d.ts +0 -54
  26. package/dist/types/patches/model-reasoning-efforts/shared.d.ts +0 -51
  27. /package/dist/types/patches/{model-reasoning-efforts → model-capabilities}/host/index.d.ts +0 -0
package/dist/client.js CHANGED
@@ -25,7 +25,7 @@ __export(index_exports, {
25
25
  inject: () => inject
26
26
  });
27
27
  module.exports = __toCommonJS(index_exports);
28
- var import_react8 = require("react");
28
+ var import_react11 = require("react");
29
29
  var import_react_dom = require("react-dom");
30
30
 
31
31
  // src/generated/patch-catalog.ts
@@ -34,16 +34,18 @@ var PATCH_CATALOG = [
34
34
  { "id": "message-delete", "name": "\u5355\u6761\u6D88\u606F\u5220\u9664", "description": "\u5220\u9664\u6307\u5B9A\u6D88\u606F\u5E76\u4FDD\u7559\u524D\u540E\u5386\u53F2\u8BB0\u5F55", "defaultEnabled": true, "order": 200, "clientKind": "message-action" },
35
35
  { "id": "session-delete", "name": "\u6C38\u4E45\u5220\u9664\u4F1A\u8BDD", "description": "\u505C\u6B62\u76EE\u6807\u4F1A\u8BDD\u5E76\u4ECE\u78C1\u76D8\u6C38\u4E45\u5220\u9664\uFF0C\u4E0D\u5F71\u54CD\u539F\u751F\u5F52\u6863", "defaultEnabled": true, "order": 300, "clientKind": "standalone" },
36
36
  { "id": "conversation-markdown-export", "name": "\u5BFC\u51FA\u5B8C\u6574\u804A\u5929\u8BB0\u5F55", "description": "\u5C06\u5F53\u524D\u4F1A\u8BDD\u7684\u5B8C\u6574\u804A\u5929\u8BB0\u5F55\u4E0B\u8F7D\u4E3A Markdown \u6587\u4EF6", "defaultEnabled": true, "order": 400, "clientKind": "standalone" },
37
- { "id": "model-reasoning-efforts", "name": "\u6A21\u578B\u601D\u8003\u5F3A\u5EA6", "description": "\u5728\u6A21\u578B\u914D\u7F6E\u754C\u9762\u4E3A\u6BCF\u4E2A\u6A21\u578B\u914D\u7F6E\u652F\u6301\u7684\u601D\u8003\u5F3A\u5EA6\u5E76\u5199\u5165 settings.yaml \u7684 reasoningEfforts", "defaultEnabled": true, "order": 500, "clientKind": "standalone" },
38
- { "id": "session-auto-title", "name": "\u4F1A\u8BDD\u81EA\u52A8\u547D\u540D", "description": "\u65B0\u4F1A\u8BDD\u9996\u6761\u9700\u6C42\u540E\uFF0C\u4F7F\u7528\u5F53\u524D\u6A21\u578B\u751F\u6210\u300C\u7C7B\u578B \xB7 \u5177\u4F53\u4EFB\u52A1\u300D\u6807\u9898\uFF1B\u4FDD\u7559\u624B\u52A8\u547D\u540D\uFF0C\u5931\u8D25\u65F6\u4FDD\u7559\u539F\u6709\u6807\u9898", "defaultEnabled": true, "order": 600, "clientKind": "standalone" }
37
+ { "id": "model-capabilities", "name": "\u6A21\u578B\u80FD\u529B\u914D\u7F6E", "description": "\u5728\u6A21\u578B\u914D\u7F6E\u9875\u8BBE\u7F6E\u6BCF\u4E2A\u6A21\u578B\u7684\u8BC6\u56FE\u80FD\u529B\u3001\u53EF\u9009\u601D\u8003\u7C7B\u578B\u4E0E\u601D\u8003\u53C2\u6570\u683C\u5F0F", "defaultEnabled": true, "order": 500, "clientKind": "standalone" },
38
+ { "id": "session-auto-title", "name": "\u4F1A\u8BDD\u81EA\u52A8\u547D\u540D", "description": "\u65B0\u4F1A\u8BDD\u9996\u6761\u9700\u6C42\u540E\uFF0C\u4F7F\u7528\u5F53\u524D\u6A21\u578B\u751F\u6210\u300C\u7C7B\u578B \xB7 \u5177\u4F53\u4EFB\u52A1\u300D\u6807\u9898\uFF1B\u4FDD\u7559\u624B\u52A8\u547D\u540D\uFF0C\u5931\u8D25\u65F6\u4FDD\u7559\u539F\u6709\u6807\u9898", "defaultEnabled": true, "order": 600, "clientKind": "standalone" },
39
+ { "id": "projectless-tasks", "name": "\u72EC\u7ACB\u4EFB\u52A1", "description": "\u5728\u5DE5\u4F5C\u533A\u4E0B\u62C9\u6846\u9009\u62E9\u72EC\u7ACB\u4EFB\u52A1\uFF0C\u6216\u6E05\u9664\u5DF2\u9009\u76EE\u5F55\u5207\u6362\uFF0C\u4FDD\u7559\u8349\u7A3F\u5E76\u81EA\u52A8\u4F7F\u7528\u72EC\u7ACB\u76EE\u5F55", "defaultEnabled": true, "order": 700, "clientKind": "standalone" }
39
40
  ];
40
41
  var DEFAULT_PATCH_SETTINGS = {
41
42
  "message-edit": true,
42
43
  "message-delete": true,
43
44
  "session-delete": true,
44
45
  "conversation-markdown-export": true,
45
- "model-reasoning-efforts": true,
46
- "session-auto-title": true
46
+ "model-capabilities": true,
47
+ "session-auto-title": true,
48
+ "projectless-tasks": true
47
49
  };
48
50
  function decodePatchSettings(value) {
49
51
  if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
@@ -774,18 +776,53 @@ var clientPatch2 = {
774
776
  }
775
777
  };
776
778
 
777
- // src/patches/model-reasoning-efforts/client/index.tsx
778
- var import_react5 = require("react");
779
- var import_dsh_client_ui_primitives5 = require("@deepseek-ai/dsh-client-ui-primitives");
779
+ // src/patches/model-capabilities/client/index.tsx
780
+ var import_react6 = require("react");
780
781
 
781
- // src/patches/model-reasoning-efforts/shared.ts
782
- var MODEL_REASONING_EFFORTS_PATCH_ID = "model-reasoning-efforts";
782
+ // src/patches/model-capabilities/shared.ts
783
+ var MODEL_CAPABILITIES_PATCH_ID = "model-capabilities";
783
784
  var LLM_PI_AI_SETTINGS_NAMESPACE = "llm-pi-ai";
785
+ var LLM_DEEPSEEK_SETTINGS_NAMESPACE = "llm-deepseek";
786
+ var DEEPSEEK_PROVIDER = "deepseek-official";
787
+ var CAPABILITIES_PROTOCOL_VERSION = 2;
788
+ var DEEPSEEK_THINKING_LEVELS = ["off", "low", "high", "max"];
784
789
  var THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
790
+ var THINKING_FORMATS = [
791
+ "openai",
792
+ "deepseek",
793
+ "openrouter",
794
+ "together",
795
+ "baseten",
796
+ "zai",
797
+ "qwen",
798
+ "chat-template",
799
+ "qwen-chat-template",
800
+ "string-thinking",
801
+ "ant-ling"
802
+ ];
803
+
804
+ // src/patches/model-capabilities/client/api.ts
805
+ function decodeSnapshot(value) {
806
+ if (typeof value !== "object" || value === null) throw mismatch();
807
+ const snapshot = value;
808
+ if (snapshot.protocolVersion !== CAPABILITIES_PROTOCOL_VERSION || typeof snapshot.writable !== "boolean" || !Array.isArray(snapshot.rows) || !snapshot.rows.every((row) => {
809
+ if (typeof row !== "object" || row === null) return false;
810
+ const entry = row;
811
+ return (entry.namespace === "llm-deepseek" || entry.namespace === "llm-pi-ai") && Number.isSafeInteger(entry.revision) && Number(entry.revision) >= 0 && typeof entry.provider === "string" && typeof entry.modelId === "string" && (entry.vision === null || typeof entry.vision === "boolean") && Object.hasOwn(entry, "reasoningEfforts") && Object.hasOwn(entry, "thinkingFormat");
812
+ })) throw mismatch();
813
+ return snapshot;
814
+ }
815
+ function mismatch() {
816
+ return new Error("\u6A21\u578B\u80FD\u529B\u754C\u9762\u4E0E\u540E\u53F0\u7248\u672C\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u91CD\u542F DSH \u670D\u52A1\u540E\u5237\u65B0\u9875\u9762\uFF0C\u518D\u4FDD\u5B58\u914D\u7F6E\u3002");
817
+ }
818
+ async function readCapabilities() {
819
+ return decodeSnapshot(await callPatchApi(MODEL_CAPABILITIES_PATCH_ID, "read", {}));
820
+ }
785
821
 
786
- // src/patches/model-reasoning-efforts/client/index.tsx
822
+ // src/patches/model-capabilities/client/editor.tsx
823
+ var import_react5 = require("react");
824
+ var import_dsh_client_ui_primitives5 = require("@deepseek-ai/dsh-client-ui-primitives");
787
825
  var import_jsx_runtime5 = require("react/jsx-runtime");
788
- var EFFORT_BUTTON_ATTR = "data-dshmore-effort";
789
826
  var LEVEL_LABELS = {
790
827
  off: "\u4E0D\u601D\u8003",
791
828
  minimal: "\u6781\u7B80",
@@ -795,265 +832,355 @@ var LEVEL_LABELS = {
795
832
  xhigh: "\u6781\u9AD8",
796
833
  max: "\u6700\u9AD8"
797
834
  };
798
- function emptyDraft() {
799
- return { nonReasoning: false, levels: {} };
800
- }
801
- function draftFromServer(efforts) {
802
- if (efforts === false) return { nonReasoning: true, levels: {} };
803
- if (efforts !== null && typeof efforts === "object") {
804
- const levels = {};
835
+ function draftFromServer(capabilities) {
836
+ const efforts = capabilities.reasoningEfforts;
837
+ const levels = {};
838
+ if (efforts !== false && efforts !== null) {
805
839
  for (const level of THINKING_LEVELS) {
806
- const wire = efforts[level];
807
- if (wire !== void 0) levels[level] = { enabled: true, wire: wire ?? "" };
840
+ if (Object.hasOwn(efforts, level)) levels[level] = { enabled: true, wire: efforts[level] ?? "" };
808
841
  }
809
- return { nonReasoning: false, levels };
810
- }
811
- return emptyDraft();
812
- }
813
- function buildDict(draft) {
814
- const dict = {};
815
- for (const level of THINKING_LEVELS) {
816
- const entry = draft.levels[level];
817
- if (entry === void 0 || !entry.enabled) continue;
818
- dict[level] = level === "off" ? null : entry.wire;
819
842
  }
820
- return dict;
821
- }
822
- function summaryLabel(efforts) {
823
- if (efforts === false) return "\u4E0D\u652F\u6301\u601D\u8003";
824
- if (efforts === null || typeof efforts !== "object") return "\u672A\u914D\u7F6E";
825
- const parts = THINKING_LEVELS.filter((level) => level !== "off" && efforts[level] !== void 0).map((level) => LEVEL_LABELS[level]);
826
- return parts.length === 0 ? "\u672A\u914D\u7F6E" : parts.join("\u3001");
843
+ return {
844
+ vision: capabilities.vision === null ? "default" : capabilities.vision ? "yes" : "no",
845
+ thinking: efforts === null ? "default" : efforts === false ? "disabled" : "custom",
846
+ levels,
847
+ thinkingFormat: capabilities.thinkingFormat ?? "default"
848
+ };
827
849
  }
828
- function findModelEntries() {
829
- const entries = [];
830
- const catalogs = document.querySelectorAll('[class*="modelCatalog"]');
831
- for (const catalog of catalogs) {
832
- for (const entry of catalog.querySelectorAll('[class*="modelEntry"]')) entries.push(entry);
850
+ function capabilitiesFromDraft(draft) {
851
+ let reasoningEfforts = null;
852
+ if (draft.thinking === "disabled") reasoningEfforts = false;
853
+ if (draft.thinking === "custom") {
854
+ reasoningEfforts = {};
855
+ for (const level of THINKING_LEVELS) {
856
+ const entry = draft.levels[level];
857
+ if (!entry?.enabled) continue;
858
+ const wire = entry.wire.trim();
859
+ if (level !== "off" && wire === "") throw new Error(`\u8BF7\u586B\u5199\u300C${LEVEL_LABELS[level]}\u300D\u7684\u53C2\u6570\u503C\u3002`);
860
+ reasoningEfforts[level] = level === "off" && wire === "" ? null : wire;
861
+ }
862
+ if (!THINKING_LEVELS.some((level) => level !== "off" && draft.levels[level]?.enabled)) {
863
+ throw new Error("\u8BF7\u81F3\u5C11\u9009\u62E9\u4E00\u79CD\u601D\u8003\u7B49\u7EA7\uFF1B\u4EC5\u9700\u4E0D\u601D\u8003\u65F6\uFF0C\u8BF7\u9009\u62E9\u300C\u4E0D\u652F\u6301\u601D\u8003\u300D\u3002");
864
+ }
833
865
  }
834
- return entries;
835
- }
836
- function providerRouteOf(entry) {
837
- const editor = entry.closest('[class*="editor"]');
838
- if (editor === null) return null;
839
- const routeSpan = editor.querySelector('[class*="editorRoute"]');
840
- const route = routeSpan?.textContent?.trim();
841
- if (route !== void 0 && route !== "") return route;
842
- const rowCard = editor.closest('[class*="rowCard"]');
843
- const name = rowCard?.querySelector('[class*="rowName"]')?.textContent?.trim();
844
- return name !== void 0 && name !== "" ? name : null;
866
+ return {
867
+ vision: draft.vision === "default" ? null : draft.vision === "yes",
868
+ reasoningEfforts,
869
+ thinkingFormat: draft.thinkingFormat === "default" ? null : draft.thinkingFormat
870
+ };
845
871
  }
846
- function modelIdOf(entry) {
847
- const input = entry.querySelector('[class*="modelRow"] input[type="text"]');
848
- const id = input?.value.trim();
849
- return id !== void 0 && id !== "" ? id : null;
872
+ function summaryLabel(capabilities) {
873
+ const vision = capabilities.vision === null ? "\u8BC6\u56FE\uFF1A\u9ED8\u8BA4" : capabilities.vision ? "\u652F\u6301\u8BC6\u56FE" : "\u4E0D\u652F\u6301\u8BC6\u56FE";
874
+ const efforts = capabilities.reasoningEfforts;
875
+ const thinking = efforts === null ? "\u601D\u8003\uFF1A\u9ED8\u8BA4" : efforts === false ? "\u4E0D\u652F\u6301\u601D\u8003" : THINKING_LEVELS.filter((level) => Object.hasOwn(efforts, level)).map((level) => LEVEL_LABELS[level]).join("\u3001");
876
+ return `${vision} \xB7 ${thinking}`;
850
877
  }
851
- function EffortEditorBody({ draft, setDraft, writable, busy }) {
852
- const toggleLevel = (level, enabled) => {
853
- setDraft((current) => {
854
- const existing = current.levels[level];
855
- const levels = { ...current.levels };
856
- levels[level] = existing === void 0 ? { enabled, wire: level === "off" ? "" : level } : { ...existing, enabled };
857
- return { ...current, levels };
858
- });
859
- };
860
- const setWire = (level, wire) => {
861
- setDraft((current) => {
862
- const existing = current.levels[level];
863
- if (existing === void 0) return current;
864
- return { ...current, levels: { ...current.levels, [level]: { ...existing, wire } } };
865
- });
866
- };
867
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dshmore-effort-editor", children: [
868
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "dshmore-effort-switch", children: [
869
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
870
- "input",
871
- {
872
- type: "checkbox",
873
- role: "switch",
874
- checked: draft.nonReasoning,
875
- disabled: !writable || busy,
876
- onChange: (event) => {
877
- setDraft((current) => ({ ...current, nonReasoning: event.currentTarget.checked }));
878
- }
879
- }
880
- ),
881
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u8BE5\u6A21\u578B\u4E0D\u652F\u6301\u601D\u8003\uFF08reasoningEfforts: false\uFF09" })
878
+ function CapabilitiesEditorBody({ draft, setDraft, disabled, api: api3 }) {
879
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dshmore-capabilities-fields", children: [
880
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "dshmore-capabilities-field", children: [
881
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u8BC6\u56FE\u80FD\u529B" }),
882
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("select", { "aria-label": "\u8BC6\u56FE\u80FD\u529B", value: draft.vision, disabled, onChange: (event) => {
883
+ const vision = event.currentTarget.value;
884
+ setDraft((current) => ({ ...current, vision }));
885
+ }, children: [
886
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "default", children: "\u6CBF\u7528\u9ED8\u8BA4" }),
887
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "yes", children: "\u652F\u6301\u8BC6\u56FE" }),
888
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "no", children: "\u4E0D\u652F\u6301\u8BC6\u56FE\uFF08\u4EC5\u6587\u5B57\uFF09" })
889
+ ] })
882
890
  ] }),
883
- !draft.nonReasoning && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "dshmore-effort-levels", children: THINKING_LEVELS.map((level) => {
884
- const entry = draft.levels[level];
885
- const enabled = entry?.enabled === true;
886
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "dshmore-effort-level", children: [
887
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
888
- "input",
889
- {
890
- type: "checkbox",
891
- checked: enabled,
892
- disabled: !writable || busy,
893
- onChange: (event) => {
894
- toggleLevel(level, event.currentTarget.checked);
895
- }
896
- }
897
- ),
898
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "dshmore-effort-level-label", children: LEVEL_LABELS[level] }),
899
- enabled && level !== "off" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
900
- "input",
901
- {
902
- className: "dshmore-effort-wire",
903
- type: "text",
904
- value: entry?.wire ?? "",
905
- disabled: !writable || busy,
906
- placeholder: "\u7EBF\u4E0A\u503C",
907
- "aria-label": `${LEVEL_LABELS[level]} \u7684\u7EBF\u4E0A\u503C`,
908
- onChange: (event) => {
909
- setWire(level, event.currentTarget.value);
891
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "dshmore-capabilities-field", children: [
892
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u601D\u8003\u7C7B\u578B" }),
893
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("select", { "aria-label": "\u601D\u8003\u7C7B\u578B", value: draft.thinking, disabled, onChange: (event) => {
894
+ const thinking = event.currentTarget.value;
895
+ setDraft((current) => ({ ...current, thinking }));
896
+ }, children: [
897
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "default", children: "\u6CBF\u7528\u9ED8\u8BA4" }),
898
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "disabled", children: "\u4E0D\u652F\u6301\u601D\u8003" }),
899
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "custom", children: "\u81EA\u5B9A\u4E49\u53EF\u9009\u7C7B\u578B" })
900
+ ] })
901
+ ] }),
902
+ draft.thinking === "custom" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("fieldset", { className: "dshmore-capabilities-levels", disabled, children: [
903
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("legend", { children: "\u6A21\u578B\u652F\u6301\u7684\u601D\u8003\u7B49\u7EA7" }),
904
+ (api3 === "deepseek-native" ? DEEPSEEK_THINKING_LEVELS : THINKING_LEVELS).map((level) => {
905
+ const entry = draft.levels[level];
906
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dshmore-capabilities-level", children: [
907
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { children: [
908
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "checkbox", checked: entry?.enabled === true, onChange: (event) => {
909
+ const enabled = event.currentTarget.checked;
910
+ setDraft((current) => ({ ...current, levels: {
911
+ ...current.levels,
912
+ [level]: { wire: level === "off" ? "" : level, ...current.levels[level], enabled }
913
+ } }));
914
+ } }),
915
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
916
+ LEVEL_LABELS[level],
917
+ " ",
918
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("small", { children: level })
919
+ ] })
920
+ ] }),
921
+ entry?.enabled && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
922
+ "input",
923
+ {
924
+ type: "text",
925
+ "aria-label": `${LEVEL_LABELS[level]}\u7684\u53C2\u6570\u503C`,
926
+ value: entry.wire,
927
+ readOnly: api3 === "deepseek-native",
928
+ placeholder: level === "off" ? "\u7559\u7A7A\uFF1A\u4E0D\u53D1\u9001\u53C2\u6570" : "\u53D1\u9001\u7ED9\u63A5\u53E3\u7684\u53C2\u6570\u503C",
929
+ onChange: (event) => {
930
+ const wire = event.currentTarget.value;
931
+ setDraft((current) => ({ ...current, levels: {
932
+ ...current.levels,
933
+ [level]: { enabled: true, wire }
934
+ } }));
935
+ }
910
936
  }
911
- }
912
- )
913
- ] }, level);
914
- }) })
937
+ )
938
+ ] }, level);
939
+ })
940
+ ] }),
941
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("details", { className: "dshmore-capabilities-advanced", children: [
942
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("summary", { children: [
943
+ "\u601D\u8003\u53C2\u6570\u683C\u5F0F",
944
+ draft.thinkingFormat === "default" ? "" : ` \xB7 ${draft.thinkingFormat}`
945
+ ] }),
946
+ api3 === null || api3 === "openai-completions" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "dshmore-capabilities-field", children: [
947
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u63A5\u53E3\u63A5\u53D7\u7684\u683C\u5F0F" }),
948
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("select", { "aria-label": "\u601D\u8003\u53C2\u6570\u683C\u5F0F", disabled, value: draft.thinkingFormat, onChange: (event) => {
949
+ const thinkingFormat = event.currentTarget.value;
950
+ setDraft((current) => ({ ...current, thinkingFormat }));
951
+ }, children: [
952
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "default", children: "\u6CBF\u7528\u9ED8\u8BA4\uFF08\u63D0\u4F9B\u65B9 / \u81EA\u52A8\u8BC6\u522B\uFF09" }),
953
+ THINKING_FORMATS.map((format) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: format, children: format }, format))
954
+ ] }),
955
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "dshmore-capabilities-note", children: "\u7528\u4E8E OpenAI \u517C\u5BB9\u63A5\u53E3\uFF1B\u6309\u63A5\u53E3\u8981\u6C42\u9009\u62E9 OpenAI\u3001DeepSeek\u3001Qwen \u7B49\u683C\u5F0F\u3002" })
956
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "dshmore-capabilities-note", children: "\u5F53\u524D\u63A5\u53E3\u4F7F\u7528\u539F\u751F\u601D\u8003\u534F\u8BAE\uFF0C\u65E0\u9700\u914D\u7F6E\u6B64\u9879\u3002" })
957
+ ] }),
958
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "dshmore-capabilities-note", children: "\u6CBF\u7528\u9ED8\u8BA4\u4F1A\u79FB\u9664\u8BE5\u6A21\u578B\u7684\u5BF9\u5E94\u58F0\u660E\u3002\u8BF7\u6309\u6A21\u578B\u5B9E\u9645\u80FD\u529B\u914D\u7F6E\u3002" })
915
959
  ] });
916
960
  }
917
- function EffortEditorModal({ provider, modelId, initial, writable, onClose }) {
918
- const [draft, setDraft] = (0, import_react5.useState)(() => draftFromServer(initial ?? null));
919
- const [busy, setBusy] = (0, import_react5.useState)(false);
961
+ function CapabilitiesEditorModal({ provider, modelId, namespace, onClose, onSaved }) {
962
+ const [snapshot, setSnapshot] = (0, import_react5.useState)(null);
963
+ const [draft, setDraft] = (0, import_react5.useState)(null);
920
964
  const [error, setError] = (0, import_react5.useState)(null);
965
+ const [busy, setBusy] = (0, import_react5.useState)(false);
966
+ const [attempt, setAttempt] = (0, import_react5.useState)(0);
967
+ const saving = (0, import_react5.useRef)(false);
968
+ const mounted = (0, import_react5.useRef)(false);
969
+ (0, import_react5.useEffect)(() => {
970
+ mounted.current = true;
971
+ return () => {
972
+ mounted.current = false;
973
+ };
974
+ }, []);
921
975
  (0, import_react5.useEffect)(() => {
922
- setDraft(draftFromServer(initial ?? null));
923
- }, [initial]);
924
- const known = initial !== void 0;
976
+ let cancelled = false;
977
+ setError(null);
978
+ void readCapabilities().then((next) => {
979
+ if (cancelled) return;
980
+ setSnapshot(next);
981
+ const row2 = next.rows.find((entry) => entry.namespace === namespace && entry.provider === provider && entry.modelId === modelId);
982
+ setDraft(row2 === void 0 ? null : draftFromServer(row2));
983
+ }).catch((caught) => {
984
+ if (!cancelled) setError(apiErrorText(caught));
985
+ });
986
+ return () => {
987
+ cancelled = true;
988
+ };
989
+ }, [namespace, provider, modelId, attempt]);
990
+ const row = snapshot?.rows.find((entry) => entry.provider === provider && entry.modelId === modelId);
925
991
  const save = async () => {
926
- if (!known) return;
927
- const payload = draft.nonReasoning ? false : buildDict(draft);
928
- if (payload !== false && !THINKING_LEVELS.some((level) => level !== "off" && payload[level] !== void 0)) {
929
- setError("\u81F3\u5C11\u9700\u8981\u5F00\u542F\u4E00\u4E2A\u975E\u300C\u4E0D\u601D\u8003\u300D\u7684\u601D\u8003\u7EA7\u522B\uFF0C\u6216\u4F7F\u7528\u300C\u6E05\u9664\u914D\u7F6E\u300D\u3002");
992
+ if (saving.current) return;
993
+ if (draft === null || row === void 0 || !snapshot?.writable || !Number.isSafeInteger(row.revision)) {
994
+ setError("\u6A21\u578B\u914D\u7F6E\u5C1A\u672A\u5C31\u7EEA\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u5F39\u7A97\u540E\u91CD\u8BD5\u3002");
930
995
  return;
931
996
  }
932
- setBusy(true);
933
- setError(null);
997
+ let capabilities;
934
998
  try {
935
- await callPatchApi(MODEL_REASONING_EFFORTS_PATCH_ID, "save", {
936
- provider,
937
- modelId,
938
- reasoningEfforts: payload
939
- });
940
- onClose();
999
+ capabilities = capabilitiesFromDraft(draft);
941
1000
  } catch (caught) {
942
1001
  setError(apiErrorText(caught));
943
- } finally {
944
- setBusy(false);
1002
+ return;
945
1003
  }
946
- };
947
- const clear = async () => {
948
- if (!known) return;
1004
+ saving.current = true;
949
1005
  setBusy(true);
950
1006
  setError(null);
951
1007
  try {
952
- await callPatchApi(MODEL_REASONING_EFFORTS_PATCH_ID, "save", {
1008
+ const next = decodeSnapshot(await callPatchApi(MODEL_CAPABILITIES_PATCH_ID, "save", {
1009
+ namespace,
953
1010
  provider,
954
1011
  modelId,
955
- reasoningEfforts: null
956
- });
957
- onClose();
1012
+ expectedRevision: row.revision,
1013
+ ...capabilities
1014
+ }));
1015
+ if (mounted.current) {
1016
+ onSaved(next);
1017
+ onClose();
1018
+ }
958
1019
  } catch (caught) {
959
- setError(apiErrorText(caught));
1020
+ if (mounted.current) setError(apiErrorText(caught));
960
1021
  } finally {
961
- setBusy(false);
1022
+ saving.current = false;
1023
+ if (mounted.current) setBusy(false);
962
1024
  }
963
1025
  };
964
1026
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
965
1027
  import_dsh_client_ui_primitives5.Modal,
966
1028
  {
967
1029
  open: true,
968
- onClose,
969
- title: `\u601D\u8003\u5F3A\u5EA6 \xB7 ${modelId}`,
1030
+ onClose: () => {
1031
+ if (!saving.current) onClose();
1032
+ },
1033
+ title: `\u6A21\u578B\u80FD\u529B \xB7 ${modelId}`,
970
1034
  closeLabel: "\u5173\u95ED",
971
1035
  description: `\u63D0\u4F9B\u65B9 ${provider}`,
972
1036
  footer: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
973
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", disabled: busy, onClick: onClose, children: "\u5173\u95ED" }),
974
- known && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", disabled: !writable || busy, onClick: () => {
975
- void clear();
976
- }, children: "\u6E05\u9664\u914D\u7F6E" }),
977
- known && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_dsh_client_ui_primitives5.Button, { variant: "primary", disabled: !writable || busy, onClick: () => {
978
- void save();
979
- }, children: busy ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58" })
1037
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", disabled: busy, onClick: onClose, children: "\u53D6\u6D88" }),
1038
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1039
+ import_dsh_client_ui_primitives5.Button,
1040
+ {
1041
+ variant: "primary",
1042
+ disabled: busy || draft === null || row === void 0 || !snapshot?.writable,
1043
+ onClick: () => {
1044
+ void save();
1045
+ },
1046
+ children: busy ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58"
1047
+ }
1048
+ )
980
1049
  ] }),
981
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dshmore-effort-dialog-body", children: [
982
- !known && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "dshmore-effort-note", children: "\u8BE5\u6A21\u578B\u5C1A\u672A\u4FDD\u5B58\u5230 settings.yaml\uFF0C\u8BF7\u5148\u5728\u4E0A\u65B9\u4FDD\u5B58\u63D0\u4F9B\u65B9\u914D\u7F6E\u3002" }),
983
- known && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(EffortEditorBody, { draft, setDraft, writable, busy }),
984
- !writable && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "dshmore-effort-warn", children: "\u5F53\u524D Settings \u5B58\u50A8\u4E3A\u53EA\u8BFB\uFF0C\u65E0\u6CD5\u4FDD\u5B58\u4FEE\u6539\u3002" }),
985
- error !== null && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "dshmore-effort-error", children: error })
1050
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dshmore-capabilities-dialog", children: [
1051
+ snapshot === null && error === null && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "dshmore-capabilities-note", children: "\u6B63\u5728\u8BFB\u53D6\u6A21\u578B\u914D\u7F6E\u2026" }),
1052
+ snapshot !== null && row === void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "dshmore-capabilities-note", children: "\u8BF7\u5148\u4FDD\u5B58\u63D0\u4F9B\u65B9\u914D\u7F6E\uFF0C\u518D\u6253\u5F00\u8BE5\u6A21\u578B\u7684\u80FD\u529B\u8BBE\u7F6E\u3002" }),
1053
+ draft !== null && row !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1054
+ CapabilitiesEditorBody,
1055
+ {
1056
+ draft,
1057
+ setDraft: (update) => {
1058
+ setDraft((current) => current === null ? null : update(current));
1059
+ },
1060
+ disabled: busy || !snapshot?.writable,
1061
+ api: row.api
1062
+ }
1063
+ ),
1064
+ snapshot !== null && !snapshot.writable && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "dshmore-capabilities-note", children: "\u5F53\u524D\u914D\u7F6E\u4E3A\u53EA\u8BFB\u3002" }),
1065
+ error !== null && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { role: "alert", className: "dshmore-capabilities-error", children: error }),
1066
+ snapshot === null && error !== null && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", onClick: () => {
1067
+ setAttempt((value) => value + 1);
1068
+ }, children: "\u91CD\u8BD5" })
986
1069
  ] })
987
1070
  }
988
1071
  );
989
1072
  }
990
- function ModelsPageEffortPortal(props) {
991
- const settings = (0, import_react5.useSyncExternalStore)(props.activation.subscribe, props.activation.getSnapshot, props.activation.getSnapshot);
992
- const enabled = settings[MODEL_REASONING_EFFORTS_PATCH_ID];
993
- const scopeSnapshot = (0, import_react5.useSyncExternalStore)(props.scope.subscribe, props.scope.getSnapshot, props.scope.getSnapshot);
994
- const [editing, setEditing] = (0, import_react5.useState)(null);
995
- const [data, setData] = (0, import_react5.useState)(null);
996
- const dataRef = (0, import_react5.useRef)(data);
1073
+
1074
+ // src/patches/model-capabilities/client/model-entries.ts
1075
+ function findModelEntries() {
1076
+ const entries = [];
1077
+ const catalogs = document.querySelectorAll('[class*="modelCatalog"]');
1078
+ for (const catalog of catalogs) {
1079
+ for (const entry of catalog.querySelectorAll('[class*="modelEntry"]')) entries.push(entry);
1080
+ }
1081
+ return entries;
1082
+ }
1083
+ function providerRouteOf(entry) {
1084
+ const editor = entry.closest('[class*="editor"]');
1085
+ if (editor === null) return null;
1086
+ const routeSpan = editor.querySelector('[class*="editorRoute"]');
1087
+ const route = routeSpan?.textContent?.trim();
1088
+ if (route !== void 0 && route !== "") return route;
1089
+ const rowCard = editor.closest('[class*="rowCard"]');
1090
+ const name = rowCard?.querySelector('[class*="rowName"]')?.textContent?.trim();
1091
+ return name !== void 0 && name !== "" ? name : null;
1092
+ }
1093
+ function modelIdOf(entry) {
1094
+ const input = entry.querySelector('[class*="modelRow"] input[type="text"]');
1095
+ const id = input?.value.trim();
1096
+ return id !== void 0 && id !== "" ? id : null;
1097
+ }
1098
+
1099
+ // src/patches/model-capabilities/client/styles.ts
1100
+ var capabilitiesStyles = `
1101
+ .dshmore-capabilities-button { box-sizing: border-box; width: 100%; min-height: 30px; color: var(--dsw-alias-label-secondary); font: inherit; cursor: pointer; background: transparent; border: 1px dashed var(--dsw-alias-border-l3); border-radius: 6px; margin-top: 6px; padding: 5px 10px; font-size: 12px; line-height: 18px; text-align: left; overflow-wrap: anywhere; }
1102
+ .dshmore-capabilities-button:hover { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-primary); }
1103
+ .dshmore-capabilities-dialog, .dshmore-capabilities-fields { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
1104
+ .dshmore-capabilities-dialog { max-height: 65vh; overflow-y: auto; }
1105
+ .dshmore-capabilities-field { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--dsw-alias-label-secondary); }
1106
+ .dshmore-capabilities-fields select, .dshmore-capabilities-level input[type="text"] { box-sizing: border-box; min-width: 0; width: 100%; height: 32px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2); border-radius: 6px; background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); font: inherit; font-size: 13px; }
1107
+ .dshmore-capabilities-fields :disabled { opacity: .55; cursor: default; }
1108
+ .dshmore-capabilities-fields :focus-visible, .dshmore-capabilities-button:focus-visible { outline: 2px solid var(--dsw-alias-brand-primary); outline-offset: 2px; }
1109
+ .dshmore-capabilities-levels { display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 12px; border: 1px solid var(--dsw-alias-border-l3); border-radius: 8px; min-width: 0; }
1110
+ .dshmore-capabilities-levels legend { font-size: 12px; color: var(--dsw-alias-label-secondary); }
1111
+ .dshmore-capabilities-level { display: grid; grid-template-columns: minmax(100px, 1fr) minmax(120px, 1.4fr); gap: 8px; align-items: center; min-height: 32px; }
1112
+ .dshmore-capabilities-level label { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--dsw-alias-label-secondary); }
1113
+ .dshmore-capabilities-level input[type="checkbox"] { accent-color: var(--dsw-alias-state-business-primary); }
1114
+ .dshmore-capabilities-level small { color: var(--dsw-alias-label-tertiary); }
1115
+ .dshmore-capabilities-advanced { border-top: 1px solid var(--dsw-alias-border-l3); padding-top: 12px; }
1116
+ .dshmore-capabilities-advanced summary { cursor: pointer; font-size: 13px; color: var(--dsw-alias-label-secondary); }
1117
+ .dshmore-capabilities-advanced[open] summary { margin-bottom: 12px; }
1118
+ .dshmore-capabilities-note { color: var(--dsw-alias-label-tertiary); margin: 0; font-size: 12px; line-height: 18px; }
1119
+ .dshmore-capabilities-error { padding: 8px 10px; border-radius: 8px; background: rgba(208,58,58,.10); color: var(--dsw-alias-state-error-primary, rgb(220,90,90)); font-size: 12px; line-height: 18px; }
1120
+ `;
1121
+
1122
+ // src/patches/model-capabilities/client/index.tsx
1123
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1124
+ var BUTTON_ATTR = "data-dshmore-model-capabilities";
1125
+ function ModelsPageCapabilitiesPortal({ scope, deepseekScope, activation }) {
1126
+ const settings = (0, import_react6.useSyncExternalStore)(activation.subscribe, activation.getSnapshot, activation.getSnapshot);
1127
+ const enabled = settings[MODEL_CAPABILITIES_PATCH_ID];
1128
+ const scopeSnapshot = (0, import_react6.useSyncExternalStore)(scope.subscribe, scope.getSnapshot, scope.getSnapshot);
1129
+ const deepseekSnapshot = (0, import_react6.useSyncExternalStore)(deepseekScope.subscribe, deepseekScope.getSnapshot, deepseekScope.getSnapshot);
1130
+ const [editing, setEditing] = (0, import_react6.useState)(null);
1131
+ const [data, setData] = (0, import_react6.useState)(null);
1132
+ const dataRef = (0, import_react6.useRef)(data);
997
1133
  dataRef.current = data;
998
- const generation = (0, import_react5.useRef)(0);
999
- const fillingRef = (0, import_react5.useRef)(false);
1000
- const reload = (0, import_react5.useCallback)(async () => {
1001
- const current = ++generation.current;
1002
- try {
1003
- const snapshot = await callPatchApi(MODEL_REASONING_EFFORTS_PATCH_ID, "read", {});
1004
- if (generation.current !== current) return;
1005
- setData(snapshot);
1006
- if (enabled && snapshot.writable && snapshot.rows.some((row) => row.reasoningEfforts === null) && !fillingRef.current) {
1007
- fillingRef.current = true;
1008
- void callPatchApi(MODEL_REASONING_EFFORTS_PATCH_ID, "fillDefaults", {}).catch(() => void 0).finally(() => {
1009
- fillingRef.current = false;
1010
- });
1011
- }
1012
- } catch {
1134
+ (0, import_react6.useEffect)(() => {
1135
+ let cancelled = false;
1136
+ if (!enabled) {
1137
+ setEditing(null);
1138
+ setData(null);
1139
+ return;
1013
1140
  }
1014
- }, [enabled]);
1015
- (0, import_react5.useEffect)(() => {
1016
- if (enabled) void reload();
1017
- }, [enabled, reload, scopeSnapshot]);
1018
- const syncButtons = (0, import_react5.useCallback)(() => {
1141
+ void readCapabilities().then((snapshot) => {
1142
+ if (!cancelled) setData(snapshot);
1143
+ }).catch(() => {
1144
+ if (!cancelled) setData(null);
1145
+ });
1146
+ return () => {
1147
+ cancelled = true;
1148
+ };
1149
+ }, [enabled, scopeSnapshot, deepseekSnapshot]);
1150
+ const syncButtons = (0, import_react6.useCallback)(() => {
1019
1151
  if (!enabled) return;
1020
1152
  const active = /* @__PURE__ */ new Set();
1021
1153
  for (const entry of findModelEntries()) {
1022
1154
  const provider = providerRouteOf(entry);
1023
1155
  const modelId = modelIdOf(entry);
1024
- if (provider === null || modelId === null) continue;
1156
+ const modelRow = entry.querySelector('[class*="modelRow"]');
1157
+ if (provider === null || modelId === null || modelRow === null) continue;
1025
1158
  active.add(entry);
1026
- let button = entry.querySelector(`[${EFFORT_BUTTON_ATTR}]`);
1159
+ let button = entry.querySelector(`[${BUTTON_ATTR}]`);
1027
1160
  if (button === null) {
1028
1161
  button = document.createElement("button");
1029
1162
  button.type = "button";
1030
- button.className = "dshmore-effort-row-button";
1031
- button.setAttribute(EFFORT_BUTTON_ATTR, "");
1163
+ button.className = "dshmore-capabilities-button";
1164
+ button.setAttribute(BUTTON_ATTR, "");
1032
1165
  button.addEventListener("click", () => {
1033
1166
  const route = button?.dataset.provider;
1034
1167
  const model = button?.dataset.model;
1035
- if (route !== void 0 && model !== void 0) setEditing({ provider: route, modelId: model });
1168
+ if (route !== void 0 && model !== void 0) setEditing({ namespace: route === DEEPSEEK_PROVIDER ? LLM_DEEPSEEK_SETTINGS_NAMESPACE : LLM_PI_AI_SETTINGS_NAMESPACE, provider: route, modelId: model });
1036
1169
  });
1037
- const row = entry.querySelector('[class*="modelRow"]');
1038
- if (row === null) continue;
1039
- entry.insertBefore(button, row.nextSibling);
1170
+ entry.insertBefore(button, modelRow.nextSibling);
1040
1171
  }
1041
1172
  if (button.dataset.provider !== provider) button.dataset.provider = provider;
1042
1173
  if (button.dataset.model !== modelId) button.dataset.model = modelId;
1043
- const rowData = dataRef.current?.rows.find((row) => row.provider === provider && row.modelId === modelId);
1044
- const text = rowData === void 0 ? "\u601D\u8003\u5F3A\u5EA6" : `\u601D\u8003\u5F3A\u5EA6 \xB7 ${summaryLabel(rowData.reasoningEfforts)}`;
1174
+ const row = dataRef.current?.rows.find((item) => item.provider === provider && item.modelId === modelId);
1175
+ const text = row === void 0 ? "\u6A21\u578B\u80FD\u529B \xB7 \u8BC6\u56FE / \u601D\u8003\u7C7B\u578B" : `\u6A21\u578B\u80FD\u529B \xB7 ${summaryLabel(row)}`;
1045
1176
  if (button.textContent !== text) button.textContent = text;
1046
1177
  }
1047
- document.querySelectorAll(`[${EFFORT_BUTTON_ATTR}]`).forEach((button) => {
1048
- const host = button.parentElement;
1049
- if (host === null || !active.has(host)) button.remove();
1178
+ document.querySelectorAll(`[${BUTTON_ATTR}]`).forEach((button) => {
1179
+ if (button.parentElement === null || !active.has(button.parentElement)) button.remove();
1050
1180
  });
1051
1181
  }, [enabled]);
1052
- (0, import_react5.useEffect)(() => {
1053
- if (!enabled) {
1054
- document.querySelectorAll(`[${EFFORT_BUTTON_ATTR}]`).forEach((element) => element.remove());
1055
- return;
1056
- }
1182
+ (0, import_react6.useEffect)(() => {
1183
+ if (!enabled) return;
1057
1184
  let frame = null;
1058
1185
  const schedule = () => {
1059
1186
  if (frame !== null) return;
@@ -1072,61 +1199,48 @@ function ModelsPageEffortPortal(props) {
1072
1199
  document.removeEventListener("input", schedule);
1073
1200
  document.removeEventListener("change", schedule);
1074
1201
  if (frame !== null) window.cancelAnimationFrame(frame);
1075
- document.querySelectorAll(`[${EFFORT_BUTTON_ATTR}]`).forEach((element) => element.remove());
1202
+ document.querySelectorAll(`[${BUTTON_ATTR}]`).forEach((element) => element.remove());
1076
1203
  };
1077
1204
  }, [enabled, syncButtons]);
1078
- (0, import_react5.useEffect)(() => {
1205
+ (0, import_react6.useEffect)(() => {
1079
1206
  if (enabled) syncButtons();
1080
1207
  }, [enabled, syncButtons, data]);
1081
- const editingRow = editing === null ? void 0 : data?.rows.find((row) => row.provider === editing.provider && row.modelId === editing.modelId);
1082
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1083
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: effortStyles }),
1084
- editing !== null && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1085
- EffortEditorModal,
1208
+ if (!enabled) return null;
1209
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1210
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: capabilitiesStyles }),
1211
+ editing !== null && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1212
+ CapabilitiesEditorModal,
1086
1213
  {
1087
- provider: editing.provider,
1088
- modelId: editing.modelId,
1089
- initial: editingRow === void 0 ? void 0 : editingRow.reasoningEfforts,
1090
- writable: data?.writable ?? true,
1214
+ ...editing,
1091
1215
  onClose: () => {
1092
1216
  setEditing(null);
1093
- }
1094
- }
1217
+ },
1218
+ onSaved: setData
1219
+ },
1220
+ `${editing.provider}/${editing.modelId}`
1095
1221
  )
1096
1222
  ] });
1097
1223
  }
1098
- var effortStyles = `
1099
- .dshmore-effort-row-button { box-sizing: border-box; width: 100%; height: 28px; color: var(--dsw-alias-label-secondary); font: inherit; cursor: pointer; background: transparent; border: 1px dashed var(--dsw-alias-border-l3); border-radius: 6px; margin-top: 6px; padding: 0 10px; font-size: 12px; line-height: 18px; display: inline-flex; align-items: center; justify-content: flex-start; gap: 6px; }
1100
- .dshmore-effort-row-button:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-primary); }
1101
- .dshmore-effort-dialog-body { box-sizing: border-box; display: flex; flex-direction: column; gap: 12px; width: 100%; min-width: 0; overflow: hidden; }
1102
- .dshmore-effort-editor { display: flex; flex-direction: column; gap: 12px; }
1103
- .dshmore-effort-switch, .dshmore-effort-level { display: flex; align-items: center; gap: 8px; color: var(--dsw-alias-label-secondary); font-size: 13px; line-height: 20px; cursor: pointer; }
1104
- .dshmore-effort-switch input, .dshmore-effort-level input[type="checkbox"] { accent-color: var(--dsw-alias-state-business-primary); cursor: pointer; }
1105
- .dshmore-effort-levels { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px 12px; }
1106
- .dshmore-effort-level-label { flex: none; }
1107
- .dshmore-effort-wire { box-sizing: border-box; height: 28px; min-width: 0; width: 100%; font: inherit; color: var(--dsw-alias-label-primary); background: var(--dsw-alias-bg-layer-1); border: 1px solid var(--dsw-alias-border-l2); border-radius: 6px; padding: 0 8px; font-size: 12px; line-height: 18px; }
1108
- .dshmore-effort-wire:focus { border-color: var(--dsw-alias-brand-primary); outline: none; }
1109
- .dshmore-effort-wire::placeholder { color: var(--dsw-alias-label-dimmed); }
1110
- .dshmore-effort-note { color: var(--dsw-alias-label-tertiary); margin: 0; font-size: 12px; line-height: 18px; }
1111
- .dshmore-effort-warn { color: var(--dsw-alias-state-warn-label); margin: 0; font-size: 12px; line-height: 18px; }
1112
- .dshmore-effort-error { padding: 8px 10px; border-radius: 8px; background: rgba(208,58,58,.10); color: var(--dsw-alias-state-error-primary, rgb(220,90,90)); font-size: 12px; line-height: 18px; }
1113
- `;
1114
1224
  var clientPatch3 = {
1115
- id: MODEL_REASONING_EFFORTS_PATCH_ID,
1225
+ id: MODEL_CAPABILITIES_PATCH_ID,
1116
1226
  install: (ctx, activation) => {
1117
- const scope = ctx.settingsScope.bind({ namespace: LLM_PI_AI_SETTINGS_NAMESPACE });
1118
- const boundScope = {
1119
- getSnapshot: scope.getSnapshot.bind(scope),
1120
- subscribe: scope.subscribe.bind(scope),
1121
- set: scope.set.bind(scope),
1122
- unset: scope.unset.bind(scope),
1123
- mutate: scope.mutate.bind(scope)
1227
+ const bindScope = (namespace) => {
1228
+ const scope = ctx.settingsScope.bind({ namespace });
1229
+ return {
1230
+ getSnapshot: scope.getSnapshot.bind(scope),
1231
+ subscribe: scope.subscribe.bind(scope),
1232
+ set: scope.set.bind(scope),
1233
+ unset: scope.unset.bind(scope),
1234
+ mutate: scope.mutate.bind(scope)
1235
+ };
1124
1236
  };
1237
+ const boundScope = bindScope(LLM_PI_AI_SETTINGS_NAMESPACE);
1238
+ const deepseekScope = bindScope(LLM_DEEPSEEK_SETTINGS_NAMESPACE);
1125
1239
  ctx.slots.inject("shell.overlay", () => ctx.slots.register({
1126
1240
  name: "shell.overlay",
1127
- id: `${PLUGIN_NAME}-${MODEL_REASONING_EFFORTS_PATCH_ID}`,
1241
+ id: `${PLUGIN_NAME}-${MODEL_CAPABILITIES_PATCH_ID}`,
1128
1242
  order: 90
1129
- }, (props) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ModelsPageEffortPortal, { ...props, scope: boundScope, activation })));
1243
+ }, () => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ModelsPageCapabilitiesPortal, { scope: boundScope, deepseekScope, activation })));
1130
1244
  }
1131
1245
  };
1132
1246
 
@@ -1140,9 +1254,414 @@ var clientPatch4 = {
1140
1254
  }
1141
1255
  };
1142
1256
 
1257
+ // src/patches/projectless-tasks/shared.ts
1258
+ var PROJECTLESS_TASKS_PATCH_ID = "projectless-tasks";
1259
+
1260
+ // src/patches/projectless-tasks/client/adapter.tsx
1261
+ var import_react8 = require("react");
1262
+
1263
+ // src/patches/projectless-tasks/client/create-task.ts
1264
+ function createTaskStarter(sessions) {
1265
+ let pendingId;
1266
+ let flight;
1267
+ let disposed = false;
1268
+ return {
1269
+ start(beforeOpen) {
1270
+ if (disposed) return Promise.reject(new Error("\u72EC\u7ACB\u4EFB\u52A1\u8865\u4E01\u5DF2\u5173\u95ED\u3002"));
1271
+ if (flight !== void 0) return flight;
1272
+ pendingId ??= `task-${crypto.randomUUID()}`;
1273
+ const sessionId = pendingId;
1274
+ flight = (async () => {
1275
+ const location = await callPatchApi(PROJECTLESS_TASKS_PATCH_ID, "prepare", { sessionId });
1276
+ if (location.sessionId !== sessionId || typeof location.cwd !== "string" || location.cwd.length === 0) {
1277
+ throw new Error("\u72EC\u7ACB\u4EFB\u52A1\u754C\u9762\u4E0E\u540E\u53F0\u7248\u672C\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u91CD\u542F DSH\u3002");
1278
+ }
1279
+ if (disposed) return;
1280
+ const id = await sessions.create({ sessionId, cwd: location.cwd });
1281
+ if (id !== sessionId) throw new Error("\u521B\u5EFA\u7ED3\u679C\u4E0E\u72EC\u7ACB\u4EFB\u52A1\u6807\u8BC6\u4E0D\u4E00\u81F4\u3002");
1282
+ if (!disposed && beforeOpen?.(id) !== false) sessions.open(id);
1283
+ pendingId = void 0;
1284
+ })().finally(() => {
1285
+ flight = void 0;
1286
+ });
1287
+ return flight;
1288
+ },
1289
+ dispose() {
1290
+ disposed = true;
1291
+ }
1292
+ };
1293
+ }
1294
+
1295
+ // src/patches/projectless-tasks/client/draft.ts
1296
+ function transferDraft(source, target) {
1297
+ const from = source.state.getSnapshot();
1298
+ const to = target.state.getSnapshot();
1299
+ if (from.phase !== "plain" || to.phase !== "plain") throw new Error("\u8F93\u5165\u6B63\u5728\u5904\u7406\u4E2D\uFF0C\u8BF7\u7A0D\u540E\u5207\u6362\u4EFB\u52A1\u76EE\u5F55\u3002");
1300
+ if (from.draft !== "" && to.draft !== "" && from.draft !== to.draft) {
1301
+ throw new Error("\u76EE\u6807\u4EFB\u52A1\u5DF2\u6709\u5176\u4ED6\u8349\u7A3F\uFF0C\u672C\u6B21\u5207\u6362\u5DF2\u505C\u6B62\uFF0C\u539F\u8349\u7A3F\u5DF2\u4FDD\u7559\u3002");
1302
+ }
1303
+ if (from.imageIds.length > 0 && !target.addImages([...from.imageIds])) {
1304
+ throw new Error("\u6682\u65F6\u65E0\u6CD5\u8F6C\u79FB\u56FE\u7247\uFF0C\u539F\u8349\u7A3F\u5DF2\u4FDD\u7559\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");
1305
+ }
1306
+ if (from.draft !== "") target.setDraft(from.draft);
1307
+ if (from.draft !== "") source.setDraft("");
1308
+ from.imageIds.forEach((id) => source.removeImage(id));
1309
+ }
1310
+ function transferBeforeOpen(ctx, sourceId, targetId) {
1311
+ const value = ctx.sessions;
1312
+ if (typeof value !== "object" || value === null || !("scope" in value) || typeof value.scope !== "function" || !("list" in value) || typeof value.list !== "object" || value.list === null || !("getSnapshot" in value.list) || typeof value.list.getSnapshot !== "function") {
1313
+ throw new Error("\u5F53\u524D DSH \u7248\u672C\u4E0D\u652F\u6301\u4FDD\u7559\u8349\u7A3F\u5207\u6362\uFF0C\u8BF7\u68C0\u67E5\u4F1A\u8BDD\u63A5\u53E3\u3002");
1314
+ }
1315
+ const sessions = value;
1316
+ const list = sessions.list.getSnapshot();
1317
+ if (list.current !== sourceId) return false;
1318
+ if (sourceId === void 0 || sourceId === targetId) return true;
1319
+ if (list.byId[sourceId]?.blank !== true) throw new Error("\u5F53\u524D\u4F1A\u8BDD\u5DF2\u5F00\u59CB\uFF0C\u8BF7\u65B0\u5EFA\u4F1A\u8BDD\u540E\u9009\u62E9\u72EC\u7ACB\u4EFB\u52A1\u3002");
1320
+ const source = sessions.scope(sourceId);
1321
+ const target = sessions.scope(targetId);
1322
+ if (source === void 0 || target === void 0) throw new Error("\u4EFB\u52A1\u5C1A\u672A\u51C6\u5907\u597D\uFF0C\u539F\u8349\u7A3F\u5DF2\u4FDD\u7559\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");
1323
+ transferDraft(ctx.conversation.input.for(source), ctx.conversation.input.for(target));
1324
+ return true;
1325
+ }
1326
+
1327
+ // src/patches/projectless-tasks/client/picker.tsx
1328
+ var import_react7 = require("react");
1329
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1330
+ var INDEPENDENT_CHOICE_ID = "::dsh-more-independent-task";
1331
+ var INDEPENDENT_CHOICE = {
1332
+ workspaceId: INDEPENDENT_CHOICE_ID,
1333
+ title: "\u72EC\u7ACB\u4EFB\u52A1",
1334
+ path: "",
1335
+ sessionIds: [],
1336
+ createdAt: "",
1337
+ updatedAt: ""
1338
+ };
1339
+ var ChoiceContext = (0, import_react7.createContext)(void 0);
1340
+ function withIndependentChoice(snapshot) {
1341
+ return { ...snapshot, items: [INDEPENDENT_CHOICE, ...snapshot.items] };
1342
+ }
1343
+ function labelIndependentChip(anchor) {
1344
+ const label = anchor.querySelector('[class*="_workspaceLabel"]');
1345
+ if (label === null) return () => {
1346
+ };
1347
+ const text = label.textContent;
1348
+ const aria = anchor.getAttribute("aria-label");
1349
+ label.textContent = "\u72EC\u7ACB\u4EFB\u52A1";
1350
+ anchor.setAttribute("aria-label", "\u5DE5\u4F5C\u76EE\u5F55\uFF1A\u72EC\u7ACB\u4EFB\u52A1");
1351
+ return () => {
1352
+ if (label.textContent === "\u72EC\u7ACB\u4EFB\u52A1") label.textContent = text;
1353
+ if (anchor.getAttribute("aria-label") === "\u5DE5\u4F5C\u76EE\u5F55\uFF1A\u72EC\u7ACB\u4EFB\u52A1") {
1354
+ if (aria === null) anchor.removeAttribute("aria-label");
1355
+ else anchor.setAttribute("aria-label", aria);
1356
+ }
1357
+ };
1358
+ }
1359
+ function WorkspaceChoice({ owner, state, error, children }) {
1360
+ (0, import_react7.useLayoutEffect)(() => {
1361
+ const anchor = owner.anchorRef?.current;
1362
+ if (!state.independent || owner.selectedId !== void 0 || anchor === void 0 || anchor === null) return;
1363
+ return labelIndependentChip(anchor);
1364
+ });
1365
+ const clear = () => {
1366
+ owner.onClose();
1367
+ state.chooseIndependent();
1368
+ };
1369
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(ChoiceContext.Provider, { value: state, children: [
1370
+ children,
1371
+ owner.selectedId !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1372
+ "button",
1373
+ {
1374
+ type: "button",
1375
+ className: "dshmore-workspace-clear",
1376
+ "aria-label": "\u6E05\u9664\u76EE\u5F55\uFF0C\u5207\u6362\u4E3A\u72EC\u7ACB\u4EFB\u52A1",
1377
+ title: "\u6E05\u9664\u76EE\u5F55\uFF0C\u5207\u6362\u4E3A\u72EC\u7ACB\u4EFB\u52A1",
1378
+ disabled: state.busy,
1379
+ onClick: clear,
1380
+ children: "\xD7"
1381
+ }
1382
+ ),
1383
+ state.busy && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dshmore-workspace-status", role: "status", children: "\u5207\u6362\u4E2D\u2026" }),
1384
+ error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dshmore-workspace-error", role: "alert", children: error }),
1385
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `
1386
+ .dshmore-workspace-clear { display:inline-flex; align-items:center; justify-content:center; flex:none; width:22px; height:22px; margin:0 4px 0 -2px; padding:0; border:0; border-radius:50%; color:var(--dsw-alias-label-secondary); background:transparent; font:18px/1 sans-serif; cursor:pointer; }
1387
+ .dshmore-workspace-clear:hover { color:var(--dsw-alias-label-primary); background:var(--dsw-alias-interactive-bg-hover); }
1388
+ .dshmore-workspace-clear:disabled { opacity:.45; cursor:wait; }
1389
+ .dshmore-workspace-status,.dshmore-workspace-error { font-size:12px; color:var(--dsw-alias-label-secondary); }
1390
+ .dshmore-workspace-error { max-width:300px; overflow-wrap:anywhere; color:var(--dsw-alias-state-error-primary); }
1391
+ ` })
1392
+ ] });
1393
+ }
1394
+ function extendWorkspacePicker(original) {
1395
+ return function ProjectlessPicker(props) {
1396
+ const choice = (0, import_react7.useContext)(ChoiceContext);
1397
+ const snapshot = props.useWorkspaces((value) => value);
1398
+ const display = (0, import_react7.useMemo)(() => choice === void 0 ? snapshot : withIndependentChoice(snapshot), [snapshot, choice === void 0]);
1399
+ const useWorkspaces = (select) => select(display);
1400
+ return (0, import_react7.createElement)(original, {
1401
+ ...props,
1402
+ useWorkspaces,
1403
+ open: props.open && !choice?.busy,
1404
+ selectedId: props.selectedId ?? (choice?.independent ? INDEPENDENT_CHOICE_ID : void 0),
1405
+ onPick: (id) => {
1406
+ if (choice?.busy) return;
1407
+ if (id === INDEPENDENT_CHOICE_ID) {
1408
+ props.onClose();
1409
+ choice?.chooseIndependent();
1410
+ } else props.onPick(id);
1411
+ }
1412
+ });
1413
+ };
1414
+ }
1415
+ function installPickerAdapter(ctx) {
1416
+ const wrapped = /* @__PURE__ */ new Map();
1417
+ const sync = () => {
1418
+ for (const entry of ctx.slots.entries("conversation.hero.workspace")) {
1419
+ if (wrapped.has(entry) || entry.children?.["conversation.hero.workspace.directoryFlow"] === void 0 || typeof entry.component !== "function") continue;
1420
+ const original = entry.component;
1421
+ const component = extendWorkspacePicker(original);
1422
+ wrapped.set(entry, { original, component });
1423
+ entry.component = component;
1424
+ }
1425
+ };
1426
+ const unsubscribe = ctx.slots.subscribe("conversation.hero.workspace", sync);
1427
+ sync();
1428
+ const priorities = ctx.slots.entries("conversation.hero.workspace").map((entry) => entry.options.priority ?? 0);
1429
+ const fallback = ctx.slots.register({ name: "conversation.hero.workspace", priority: Math.max(0, ...priorities) + 1 }, () => null);
1430
+ return () => {
1431
+ unsubscribe();
1432
+ for (const [entry, patch] of wrapped) if (entry.component === patch.component) entry.component = patch.original;
1433
+ wrapped.clear();
1434
+ fallback();
1435
+ };
1436
+ }
1437
+
1438
+ // src/patches/projectless-tasks/client/adapter.tsx
1439
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1440
+ function isComposerOwner(owner) {
1441
+ return "variant" in owner && (owner.variant === "hero" || owner.variant === "composer");
1442
+ }
1443
+ function isWorkspaceOwner(owner) {
1444
+ return "open" in owner && typeof owner.open === "boolean" && "onPick" in owner && typeof owner.onPick === "function" && "onClose" in owner && typeof owner.onClose === "function";
1445
+ }
1446
+ function clientSessionActions(ctx) {
1447
+ const sessions = ctx.sessions;
1448
+ if (typeof sessions !== "object" || sessions === null || !("create" in sessions) || !("open" in sessions) || typeof sessions.create !== "function" || typeof sessions.open !== "function") {
1449
+ throw new Error("\u5F53\u524D DSH \u7248\u672C\u4E0D\u652F\u6301\u72EC\u7ACB\u4EFB\u52A1\uFF0C\u8BF7\u68C0\u67E5\u4F1A\u8BDD\u63A5\u53E3\u3002");
1450
+ }
1451
+ return sessions;
1452
+ }
1453
+ function unlockComposer(owner, independent, block) {
1454
+ if (!independent || owner.disabled !== true || owner.onRequestWorkspace === void 0) return owner;
1455
+ const { disabled: _disabled, onRequestWorkspace: _request, workspacePickerOpen: _picker, placeholder: _placeholder, ...rest } = owner;
1456
+ return { ...rest, ...block === void 0 ? {} : { blocked: block, placeholder: block.reason } };
1457
+ }
1458
+ function installConversationAdapter(ctx, activation) {
1459
+ const wrapped = /* @__PURE__ */ new Map();
1460
+ let live = true;
1461
+ const listeners = /* @__PURE__ */ new Set();
1462
+ const subscribeLifetime = (listener) => {
1463
+ listeners.add(listener);
1464
+ return () => {
1465
+ listeners.delete(listener);
1466
+ };
1467
+ };
1468
+ const sync = () => {
1469
+ for (const entry of ctx.slots.entries("conversation")) {
1470
+ let ProjectlessConversation2 = function(props) {
1471
+ const active = (0, import_react8.useSyncExternalStore)(subscribeLifetime, () => live);
1472
+ const settings = (0, import_react8.useSyncExternalStore)(activation.subscribe, activation.getSnapshot);
1473
+ const workspace = props.useWorkspaces((snapshot) => snapshot);
1474
+ const cwd = props.useSessions((snapshot) => props.sessionId === void 0 ? void 0 : snapshot.byId[props.sessionId]?.cwd);
1475
+ const session = props.useSession((snapshot) => snapshot);
1476
+ const block = props.useComposerBlock((value) => value);
1477
+ const enabled = active && settings[PROJECTLESS_TASKS_PATCH_ID];
1478
+ const starter = (0, import_react8.useRef)();
1479
+ const [busy, setBusy] = (0, import_react8.useState)(false);
1480
+ const [error, setError] = (0, import_react8.useState)();
1481
+ (0, import_react8.useEffect)(() => {
1482
+ if (!enabled) return;
1483
+ setBusy(false);
1484
+ setError(void 0);
1485
+ return () => {
1486
+ starter.current?.dispose();
1487
+ starter.current = void 0;
1488
+ };
1489
+ }, [enabled]);
1490
+ const independent = enabled && props.sessionId !== void 0 && session?.openState === "open" && typeof cwd === "string" && cwd.length > 0 && workspace.phase === "ready" && !workspace.items.some((item) => item.sessionIds.includes(props.sessionId));
1491
+ const chooseIndependent = () => {
1492
+ if (!enabled || busy || independent) return;
1493
+ const operation = starter.current ??= createTaskStarter(clientSessionActions(ctx));
1494
+ setBusy(true);
1495
+ setError(void 0);
1496
+ void operation.start((id) => transferBeforeOpen(ctx, props.sessionId, id)).catch((reason) => {
1497
+ if (starter.current === operation) setError(apiErrorText(reason));
1498
+ }).finally(() => {
1499
+ if (starter.current === operation) setBusy(false);
1500
+ });
1501
+ };
1502
+ const renderSlot = (name, owner, options) => {
1503
+ if (name === "conversation.composer.bar" && isComposerOwner(owner)) {
1504
+ return props.renderSlot("conversation.composer.bar", unlockComposer(owner, independent, block), options);
1505
+ }
1506
+ if (enabled && name === "conversation.hero.workspace" && isWorkspaceOwner(owner)) {
1507
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(WorkspaceChoice, { owner, state: { independent, busy, chooseIndependent }, error, children: props.renderSlot("conversation.hero.workspace", owner, options) });
1508
+ }
1509
+ return props.renderSlot(name, owner, options);
1510
+ };
1511
+ return (0, import_react8.createElement)(original, { ...props, renderSlot });
1512
+ };
1513
+ var ProjectlessConversation = ProjectlessConversation2;
1514
+ if (wrapped.has(entry) || entry.children?.["conversation.composer.bar"] === void 0 || typeof entry.component !== "function") continue;
1515
+ const original = entry.component;
1516
+ wrapped.set(entry, { original, component: ProjectlessConversation2 });
1517
+ entry.component = ProjectlessConversation2;
1518
+ }
1519
+ };
1520
+ const unsubscribe = ctx.slots.subscribe("conversation", sync);
1521
+ sync();
1522
+ const priorities = ctx.slots.entries("conversation").map((entry) => entry.options.priority ?? 0);
1523
+ const fallback = ctx.slots.register({ name: "conversation", priority: Math.max(0, ...priorities) + 1 }, () => null);
1524
+ return () => {
1525
+ live = false;
1526
+ listeners.forEach((listener) => listener());
1527
+ unsubscribe();
1528
+ for (const [entry, patch] of wrapped) {
1529
+ if (entry.component === patch.component) entry.component = patch.original;
1530
+ }
1531
+ wrapped.clear();
1532
+ fallback();
1533
+ };
1534
+ }
1535
+
1536
+ // src/patches/projectless-tasks/client/new-session.ts
1537
+ function newSessionTarget(list, workspaces, explicit) {
1538
+ if (explicit !== void 0) return { kind: "workspace", workspaceId: explicit };
1539
+ if (list.current === void 0) return { kind: "native" };
1540
+ if (list.phase !== "ready" || workspaces.phase !== "ready") return { kind: "pending" };
1541
+ const visited = /* @__PURE__ */ new Set();
1542
+ let id = list.current;
1543
+ while (id !== void 0 && !visited.has(id)) {
1544
+ visited.add(id);
1545
+ const workspace = workspaces.items.find((item) => item.sessionIds.includes(id));
1546
+ if (workspace !== void 0) return { kind: "workspace", workspaceId: workspace.workspaceId };
1547
+ const summary = list.byId[id];
1548
+ if (summary === void 0) return { kind: "pending" };
1549
+ if (summary.origin === "subagent") {
1550
+ id = summary.parentId;
1551
+ continue;
1552
+ }
1553
+ return typeof summary.cwd === "string" && summary.cwd.length > 0 ? { kind: "independent", sourceId: list.current } : { kind: "pending" };
1554
+ }
1555
+ return { kind: "pending" };
1556
+ }
1557
+ function bindNewSessionNavigation({ navigation, sessions, workspaces, activation, reportError }) {
1558
+ let disposed = false;
1559
+ let uninstall;
1560
+ const sync = () => {
1561
+ const enabled = !disposed && activation.getSnapshot()[PROJECTLESS_TASKS_PATCH_ID];
1562
+ if (!enabled) {
1563
+ uninstall?.();
1564
+ uninstall = void 0;
1565
+ return;
1566
+ }
1567
+ if (uninstall !== void 0) return;
1568
+ const descriptor = Object.getOwnPropertyDescriptor(navigation, "startSession");
1569
+ const original = navigation.startSession;
1570
+ let active = true;
1571
+ let attempt;
1572
+ const cancel = () => {
1573
+ attempt?.starter.dispose();
1574
+ attempt = void 0;
1575
+ };
1576
+ const start = (workspaceId) => {
1577
+ if (!active) return original.call(navigation, workspaceId);
1578
+ const list = sessions.list.getSnapshot();
1579
+ const target = newSessionTarget(list, workspaces.list.getSnapshot(), workspaceId);
1580
+ if (target.kind === "workspace" || target.kind === "native") {
1581
+ cancel();
1582
+ return original.call(navigation, target.kind === "workspace" ? target.workspaceId : workspaceId);
1583
+ }
1584
+ if (target.kind === "pending") {
1585
+ cancel();
1586
+ if (list.current !== void 0) reportError(list.current, new Error("\u4F1A\u8BDD\u6765\u6E90\u4ECD\u5728\u52A0\u8F7D\uFF0C\u8BF7\u7A0D\u540E\u518D\u65B0\u5EFA\u4F1A\u8BDD\u3002"));
1587
+ return;
1588
+ }
1589
+ if (attempt?.sourceId !== target.sourceId) {
1590
+ cancel();
1591
+ attempt = { sourceId: target.sourceId, starter: createTaskStarter(sessions) };
1592
+ }
1593
+ const current = attempt;
1594
+ if (current === void 0 || current.flight !== void 0) return;
1595
+ current.flight = current.starter.start(() => {
1596
+ if (!active || attempt !== current) return false;
1597
+ const destination = newSessionTarget(sessions.list.getSnapshot(), workspaces.list.getSnapshot());
1598
+ return destination.kind === "independent" && destination.sourceId === current.sourceId;
1599
+ }).catch((error) => {
1600
+ if (active && attempt === current && sessions.list.getSnapshot().current === current.sourceId) {
1601
+ reportError(current.sourceId, error);
1602
+ }
1603
+ }).finally(() => {
1604
+ delete current.flight;
1605
+ });
1606
+ };
1607
+ navigation.startSession = start;
1608
+ uninstall = () => {
1609
+ active = false;
1610
+ cancel();
1611
+ if (Object.getOwnPropertyDescriptor(navigation, "startSession")?.value !== start) return;
1612
+ if (descriptor === void 0) Reflect.deleteProperty(navigation, "startSession");
1613
+ else Object.defineProperty(navigation, "startSession", descriptor);
1614
+ };
1615
+ };
1616
+ const unsubscribe = activation.subscribe(sync);
1617
+ try {
1618
+ sync();
1619
+ } catch (error) {
1620
+ unsubscribe();
1621
+ throw error;
1622
+ }
1623
+ return () => {
1624
+ disposed = true;
1625
+ unsubscribe();
1626
+ sync();
1627
+ };
1628
+ }
1629
+ function installNewSessionNavigation(ctx, activation) {
1630
+ const navigation = ctx.get("uiWorkspace");
1631
+ const sessions = ctx.sessions;
1632
+ if (typeof navigation !== "object" || navigation === null || !("startSession" in navigation) || typeof navigation.startSession !== "function" || typeof sessions !== "object" || sessions === null || !("create" in sessions) || typeof sessions.create !== "function" || !("open" in sessions) || typeof sessions.open !== "function" || !("scope" in sessions) || typeof sessions.scope !== "function" || !("list" in sessions) || typeof sessions.list !== "object" || sessions.list === null || !("getSnapshot" in sessions.list) || typeof sessions.list.getSnapshot !== "function") {
1633
+ throw new Error("\u5F53\u524D DSH \u7248\u672C\u4E0D\u652F\u6301\u8DDF\u968F\u4F1A\u8BDD\u6765\u6E90\u65B0\u5EFA\u4EFB\u52A1\u3002");
1634
+ }
1635
+ const clientSessions = sessions;
1636
+ return bindNewSessionNavigation({
1637
+ navigation,
1638
+ sessions: clientSessions,
1639
+ workspaces: ctx.workspaces,
1640
+ activation,
1641
+ reportError: (sourceId, error) => {
1642
+ const scope = clientSessions.scope(sourceId);
1643
+ const message = `\u65B0\u5EFA\u4F1A\u8BDD\u5931\u8D25\uFF1A${apiErrorText(error)}`;
1644
+ if (scope !== void 0) ctx.conversation.input.for(scope).notify("error", message);
1645
+ else ctx.logger.warn(message);
1646
+ }
1647
+ });
1648
+ }
1649
+
1650
+ // src/patches/projectless-tasks/client/index.tsx
1651
+ var clientPatch5 = {
1652
+ id: PROJECTLESS_TASKS_PATCH_ID,
1653
+ install: (ctx, activation) => {
1654
+ ctx.inject(["conversation", "uiWorkspace"], (scope) => {
1655
+ scope.effect(() => installNewSessionNavigation(scope, activation));
1656
+ scope.slots.inject("conversation", () => installConversationAdapter(scope, activation));
1657
+ scope.slots.inject("conversation.hero.workspace", () => installPickerAdapter(scope));
1658
+ });
1659
+ }
1660
+ };
1661
+
1143
1662
  // src/generated/client-registry.ts
1144
1663
  var MESSAGE_ACTION_PATCHES = [{ id: "message-edit", order: 100, useActions: useMessageActions }, { id: "message-delete", order: 200, useActions: useMessageActions2 }];
1145
- var CLIENT_PATCHES = [clientPatch, clientPatch2, clientPatch3, clientPatch4];
1664
+ var CLIENT_PATCHES = [clientPatch, clientPatch2, clientPatch3, clientPatch4, clientPatch5];
1146
1665
 
1147
1666
  // src/kernel/client/activation.ts
1148
1667
  var ClientPatchActivation = class {
@@ -1165,19 +1684,19 @@ var ClientPatchActivation = class {
1165
1684
  };
1166
1685
 
1167
1686
  // src/kernel/client/config-card.tsx
1168
- var import_react6 = require("react");
1687
+ var import_react9 = require("react");
1169
1688
  var import_dsh_client_ui_primitives6 = require("@deepseek-ai/dsh-client-ui-primitives");
1170
- var import_jsx_runtime6 = require("react/jsx-runtime");
1689
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1171
1690
  function PatchConfigCard({ activation, initiallyOpen = false }) {
1172
- const scope = (0, import_react6.useSyncExternalStore)(
1691
+ const scope = (0, import_react9.useSyncExternalStore)(
1173
1692
  activation.subscribe,
1174
1693
  activation.getSettingsSnapshot,
1175
1694
  activation.getSettingsSnapshot
1176
1695
  );
1177
1696
  const settings = activation.getSnapshot();
1178
- const [open, setOpen] = (0, import_react6.useState)(initiallyOpen);
1179
- const [busy, setBusy] = (0, import_react6.useState)(/* @__PURE__ */ new Set());
1180
- const [error, setError] = (0, import_react6.useState)(null);
1697
+ const [open, setOpen] = (0, import_react9.useState)(initiallyOpen);
1698
+ const [busy, setBusy] = (0, import_react9.useState)(/* @__PURE__ */ new Set());
1699
+ const [error, setError] = (0, import_react9.useState)(null);
1181
1700
  if (scope.status === "unavailable") return null;
1182
1701
  const update = async (id, enabled) => {
1183
1702
  setBusy((current) => /* @__PURE__ */ new Set([...current, id]));
@@ -1194,9 +1713,9 @@ function PatchConfigCard({ activation, initiallyOpen = false }) {
1194
1713
  });
1195
1714
  }
1196
1715
  };
1197
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("li", { className: `dshmore-config-card${open ? " dshmore-config-card-open" : ""}`, children: [
1198
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: styles }),
1199
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1716
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("li", { className: `dshmore-config-card${open ? " dshmore-config-card-open" : ""}`, children: [
1717
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("style", { children: styles }),
1718
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1200
1719
  "button",
1201
1720
  {
1202
1721
  type: "button",
@@ -1207,23 +1726,23 @@ function PatchConfigCard({ activation, initiallyOpen = false }) {
1207
1726
  setOpen((current) => !current);
1208
1727
  },
1209
1728
  children: [
1210
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "dshmore-config-heading-copy", children: [
1211
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "DSH More" }),
1212
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "\u52A8\u6001\u5F00\u542F\u6216\u5173\u95ED\u72EC\u7ACB\u8865\u4E01\uFF0C\u9ED8\u8BA4\u5168\u90E8\u5F00\u542F\u3002" })
1729
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "dshmore-config-heading-copy", children: [
1730
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: "DSH More" }),
1731
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "\u52A8\u6001\u5F00\u542F\u6216\u5173\u95ED\u72EC\u7ACB\u8865\u4E01\uFF0C\u9ED8\u8BA4\u5168\u90E8\u5F00\u542F\u3002" })
1213
1732
  ] }),
1214
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dsh_client_ui_primitives6.IconChevronDownOutline14, { className: `dshmore-config-chevron${open ? " dshmore-config-chevron-open" : ""}` })
1733
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_dsh_client_ui_primitives6.IconChevronDownOutline14, { className: `dshmore-config-chevron${open ? " dshmore-config-chevron-open" : ""}` })
1215
1734
  ]
1216
1735
  }
1217
1736
  ),
1218
- open && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dshmore-config-body", children: [
1219
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "dshmore-config-list", children: PATCH_CATALOG.map((patch) => {
1737
+ open && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "dshmore-config-body", children: [
1738
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "dshmore-config-list", children: PATCH_CATALOG.map((patch) => {
1220
1739
  const waiting = busy.has(patch.id);
1221
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "dshmore-config-row", children: [
1222
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "dshmore-config-copy", children: [
1223
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: patch.name }),
1224
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: patch.description })
1740
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "dshmore-config-row", children: [
1741
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "dshmore-config-copy", children: [
1742
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: patch.name }),
1743
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: patch.description })
1225
1744
  ] }),
1226
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1745
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1227
1746
  "input",
1228
1747
  {
1229
1748
  type: "checkbox",
@@ -1238,9 +1757,9 @@ function PatchConfigCard({ activation, initiallyOpen = false }) {
1238
1757
  )
1239
1758
  ] }, patch.id);
1240
1759
  }) }),
1241
- scope.status === "loading" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "dshmore-config-note", children: "\u6B63\u5728\u8BFB\u53D6\u63D2\u4EF6\u914D\u7F6E\u2026" }),
1242
- scope.status === "ready" && !scope.writable && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "dshmore-config-note", children: "\u5F53\u524D Settings \u5B58\u50A8\u4E3A\u53EA\u8BFB\u3002" }),
1243
- error !== null && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "dshmore-config-error", children: error })
1760
+ scope.status === "loading" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "dshmore-config-note", children: "\u6B63\u5728\u8BFB\u53D6\u63D2\u4EF6\u914D\u7F6E\u2026" }),
1761
+ scope.status === "ready" && !scope.writable && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "dshmore-config-note", children: "\u5F53\u524D Settings \u5B58\u50A8\u4E3A\u53EA\u8BFB\u3002" }),
1762
+ error !== null && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "dshmore-config-error", children: error })
1244
1763
  ] })
1245
1764
  ] });
1246
1765
  }
@@ -1249,14 +1768,14 @@ function installPatchConfigCard(ctx, activation) {
1249
1768
  name: "settings.plugin.item",
1250
1769
  key: PATCH_SETTINGS_NAMESPACE,
1251
1770
  priority: 90
1252
- }, (props) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PatchConfigCard, { ...props, activation })));
1771
+ }, (props) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PatchConfigCard, { ...props, activation })));
1253
1772
  }
1254
1773
 
1255
1774
  // src/kernel/message-visibility.ts
1256
1775
  var MESSAGE_VISIBILITY_PROJECTION_KEY = "dshMoreMessageDelete";
1257
1776
 
1258
1777
  // src/platform/dsh/client/message-targets.tsx
1259
- var import_react7 = require("react");
1778
+ var import_react10 = require("react");
1260
1779
 
1261
1780
  // src/platform/dsh/client/message-content.ts
1262
1781
  function contentText(content) {
@@ -1394,17 +1913,17 @@ function trajectorySourceSeq(row) {
1394
1913
  return Number.isSafeInteger(seq) && seq >= 0 ? seq : void 0;
1395
1914
  }
1396
1915
  function useMessageTargets(props, hiddenSeqs, hiddenTrajectoryKeys, active = true) {
1397
- const selector = (0, import_react7.useMemo)(() => createMessageSurfaceSelector(active), [active, props.sessionId]);
1916
+ const selector = (0, import_react10.useMemo)(() => createMessageSurfaceSelector(active), [active, props.sessionId]);
1398
1917
  const surface = props.useChat(selector);
1399
- const surfaceRef = (0, import_react7.useRef)(surface);
1400
- const hiddenSeqsRef = (0, import_react7.useRef)(hiddenSeqs);
1401
- const hiddenTrajectoryKeysRef = (0, import_react7.useRef)(hiddenTrajectoryKeys);
1918
+ const surfaceRef = (0, import_react10.useRef)(surface);
1919
+ const hiddenSeqsRef = (0, import_react10.useRef)(hiddenSeqs);
1920
+ const hiddenTrajectoryKeysRef = (0, import_react10.useRef)(hiddenTrajectoryKeys);
1402
1921
  surfaceRef.current = surface;
1403
1922
  hiddenSeqsRef.current = hiddenSeqs;
1404
1923
  hiddenTrajectoryKeysRef.current = hiddenTrajectoryKeys;
1405
- const [targets, setTargets] = (0, import_react7.useState)([]);
1406
- const requestFullScanRef = (0, import_react7.useRef)(null);
1407
- (0, import_react7.useLayoutEffect)(() => {
1924
+ const [targets, setTargets] = (0, import_react10.useState)([]);
1925
+ const requestFullScanRef = (0, import_react10.useRef)(null);
1926
+ (0, import_react10.useLayoutEffect)(() => {
1408
1927
  if (!active) {
1409
1928
  setTargets((current) => current.length === 0 ? current : []);
1410
1929
  return;
@@ -1528,21 +2047,21 @@ function useMessageTargets(props, hiddenSeqs, hiddenTrajectoryKeys, active = tru
1528
2047
  for (const host of document.querySelectorAll("[data-dshmore-message-actions]")) host.remove();
1529
2048
  };
1530
2049
  }, [active, props.sessionId]);
1531
- (0, import_react7.useLayoutEffect)(() => {
2050
+ (0, import_react10.useLayoutEffect)(() => {
1532
2051
  requestFullScanRef.current?.();
1533
2052
  }, [surface, hiddenSeqs, hiddenTrajectoryKeys]);
1534
2053
  return targets;
1535
2054
  }
1536
2055
 
1537
2056
  // src/client/index.tsx
1538
- var import_jsx_runtime7 = require("react/jsx-runtime");
2057
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1539
2058
  var inject = ["slots", "sessions", "workspaces", "settingsScope"];
1540
2059
  function MessageActionPatchController({ patch, props, targets, enabled }) {
1541
2060
  const actions = patch.useActions(props, enabled);
1542
2061
  const style = { "--dshmore-action-order": patch.order };
1543
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2062
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1544
2063
  enabled && targets.map((target) => (0, import_react_dom.createPortal)(
1545
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dshmore-action-contribution", style, children: actions.renderAction(target) }),
2064
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dshmore-action-contribution", style, children: actions.renderAction(target) }),
1546
2065
  target.host,
1547
2066
  `${patch.id}:${target.key}`
1548
2067
  )),
@@ -1550,15 +2069,15 @@ function MessageActionPatchController({ patch, props, targets, enabled }) {
1550
2069
  ] });
1551
2070
  }
1552
2071
  function MessageActionsController(props) {
1553
- const settings = (0, import_react8.useSyncExternalStore)(props.activation.subscribe, props.activation.getSnapshot);
2072
+ const settings = (0, import_react11.useSyncExternalStore)(props.activation.subscribe, props.activation.getSnapshot);
1554
2073
  const projected = props.useProjection(MESSAGE_VISIBILITY_PROJECTION_KEY);
1555
- const hiddenSeqs = (0, import_react8.useMemo)(() => new Set(projected?.deletedSeqs ?? []), [projected]);
1556
- const hiddenTrajectoryKeys = (0, import_react8.useMemo)(() => new Set(projected?.hiddenTrajectoryKeys ?? []), [projected]);
2074
+ const hiddenSeqs = (0, import_react11.useMemo)(() => new Set(projected?.deletedSeqs ?? []), [projected]);
2075
+ const hiddenTrajectoryKeys = (0, import_react11.useMemo)(() => new Set(projected?.hiddenTrajectoryKeys ?? []), [projected]);
1557
2076
  const messageActionsEnabled = MESSAGE_ACTION_PATCHES.some((patch) => settings[patch.id]);
1558
2077
  const targets = useMessageTargets(props, hiddenSeqs, hiddenTrajectoryKeys, messageActionsEnabled);
1559
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1560
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: styles }),
1561
- MESSAGE_ACTION_PATCHES.map((patch) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2078
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2079
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("style", { children: styles }),
2080
+ MESSAGE_ACTION_PATCHES.map((patch) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1562
2081
  MessageActionPatchController,
1563
2082
  {
1564
2083
  patch,
@@ -1581,7 +2100,7 @@ function apply(ctx) {
1581
2100
  name: "conversation.session.header.utilities",
1582
2101
  id: `${PLUGIN_NAME}-message-actions`,
1583
2102
  order: 90
1584
- }, (props) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MessageActionsController, { ...props, ctx, activation })));
2103
+ }, (props) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MessageActionsController, { ...props, ctx, activation })));
1585
2104
  for (const patch of CLIENT_PATCHES) patch.install(ctx, activation);
1586
2105
  }
1587
2106
  return module.exports; } });