dsh-my-go 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,12 +1,3 @@
1
- <!-- deepseek-harness-meta
2
- {
3
- "name": "MyGO 编排器",
4
- "version": "0.2.2",
5
- "tags": ["preset", "模式预设"],
6
- "description": "把每一步路由到最合适模型的智能体编排器"
7
- }
8
- -->
9
-
10
1
  # MyGO!!!!! 编排调度 | DSH
11
2
 
12
3
  > **My** tasks, where to **GO**?????
@@ -24,7 +15,7 @@ dsh-my-go 是构建在 [DeepSeek Harness](https://github.com/deepseek-ai/deepsee
24
15
  - **7 个专业工种**:Hermes(快速执行)、Explore(检索)、Librarian(文档)、Multimodal Looker(看图)、Hephaestus(写代码)、Prometheus(规划)、Oracle(最后手段:调试 + 终验,仅当其他工种无法胜任时启用)。
25
16
  - **按工种绑定模型**:快活小工用轻模型(如 mimo-v2.5),重活用重模型(如 deepseek-v4-pro-0813)。
26
17
  - **4 个通信工具**:`go_work`(派发)、`continue`(驳回/追问)、`need_help`(求助挂起)、`forward`(转发),加 `orchestration_status`(状态总览)和 `list_subagents`(列出已有 sub-agent 及其最后 prompt)。
27
- - **步骤级调度**:Prometheus 把需求拆成步骤序列,Sisyphus 逐步骤选择最省 token 的工种——轻活派轻工种、重活派重工种、同工种上下文连续则 `continue` 复用。
18
+ - **步骤级调度**:Prometheus 把需求拆成步骤序列,Sisyphus 逐步骤选择最省 token 的工种——**按任务难度分配(不按需求难度)**:指令明确、步骤具体的执行活优先派 Hermes,需要设计/推理的才升级 Hephaestus,仅疑难/极端复杂才到 Oracle;同工种上下文连续则 `continue` 复用。
28
19
  - **Sisyphus 质检**:结论不达标驳回重做,被驳回的子智能体保留上下文继续。
29
20
  - **WebUI 配置**:每个工种的模型 / 思考档位 / DSV4P0813 补丁开关,均可在 DSH 设置页配置。
30
21
  - **DSH 适配**:权限请求、问题询问由主智能体执行。
@@ -157,6 +148,15 @@ bunx tsc --noEmit # 类型检查
157
148
  bun run test # 冒烟测试
158
149
  ```
159
150
 
151
+ ## 致谢
152
+
153
+ 感谢以下开发者对 dsh-my-go 生态的独立维护与贡献:
154
+
155
+ - [Tisitan/dsh-my-go](https://github.com/Tisitan/dsh-mygo):[@Tisitan](https://github.com/Tisitan) 的维护性 fork。
156
+ - 本项目 cherry-pick 了此下游的部分提交,尽管由于分支作者没有设置公开 Email 并禁用了 Issue 故未能取得联系,特此致谢!感谢您对开源项目的贡献。
157
+
158
+ 开源的意义在于接力,感谢每一位在暗处推动轮子前进的人。
159
+
160
160
  ## 维护状态
161
161
 
162
162
  - 仍在积极开发中,可能有少量 Bug 尚存,欢迎提交 Issue
@@ -39,7 +39,19 @@ var React = __toESM(require("react"), 1);
39
39
  var name = "dsh-my-go";
40
40
  var inject = ["slots", "settingsScope", "connection"];
41
41
  var AGENT_TYPES = ["sisyphus", "hermes", "explore", "librarian", "looker", "hephaestus", "prometheus", "oracle"];
42
- var AGENT_LABELS = { sisyphus: "Sisyphus", hermes: "Hermes", explore: "Explore", librarian: "Librarian", looker: "Looker", hephaestus: "Hephaestus", prometheus: "Prometheus", oracle: "Oracle" };
42
+ var AGENT_LABELS = {
43
+ sisyphus: "\u603B\u8C03\u5EA6\xB7\u8D28\u68C0 Sisyphus",
44
+ hermes: "\u5FEB\u901F\u6267\u884C Hermes",
45
+ explore: "\u5FEB\u901F\u68C0\u7D22 Explore",
46
+ librarian: "\u6587\u6863\u67E5\u8BE2 Librarian",
47
+ looker: "\u591A\u6A21\u6001\u770B\u56FE Looker",
48
+ hephaestus: "\u4EE3\u7801\u7F16\u5199 Hephaestus",
49
+ prometheus: "\u9700\u6C42\u89C4\u5212 Prometheus",
50
+ oracle: "\u7591\u96BE\u515C\u5E95\xB7\u7EC8\u9A8C Oracle"
51
+ };
52
+ var typeLabel = (t) => AGENT_LABELS[t] ?? String(t ?? "?");
53
+ var INTENT_LABELS = { explore: "\u68C0\u7D22", read_doc: "\u67E5\u6587\u6863", look_image: "\u770B\u56FE", replan: "\u8BF7\u6C42\u6362\u5DE5\u79CD", execute: "\u8BF7\u6C42\u4EE3\u6267\u884C", ask_user: "\u8BF7\u6C42\u95EE\u7528\u6237" };
54
+ var intentLabel = (i) => INTENT_LABELS[i] ?? String(i ?? "?");
43
55
  function apply(ctx) {
44
56
  const client = ctx;
45
57
  const slots = client.get("slots");
@@ -93,14 +105,13 @@ function apply(ctx) {
93
105
  }
94
106
  }
95
107
  function TreePanel(_props) {
96
- const [open, setOpen] = React.useState(panelOpen);
97
108
  const [, force] = React.useState(0);
98
109
  React.useEffect(() => {
99
- const unsub2 = () => listeners.delete(force);
100
- listeners.add(force);
101
- return unsub2;
110
+ const rerender = () => force((c) => c + 1);
111
+ listeners.add(rerender);
112
+ return () => listeners.delete(rerender);
102
113
  }, []);
103
- if (!open) return null;
114
+ if (!panelOpen) return null;
104
115
  const s = snapshot;
105
116
  const node = (label, status, childId, onClick) => React.createElement(
106
117
  "div",
@@ -114,7 +125,7 @@ function apply(ctx) {
114
125
  );
115
126
  const jump = (childId) => {
116
127
  if (sessions && typeof sessions.openSubagent === "function") {
117
- sessions.openSubagent({ parentSessionId: "", childSessionId: childId, mode: "continuable" });
128
+ sessions.openSubagent({ parentSessionId: snapshot.parentSessionId ?? "", childSessionId: childId, mode: "continuable" });
118
129
  }
119
130
  };
120
131
  const current = s.current;
@@ -141,25 +152,28 @@ function apply(ctx) {
141
152
  "div",
142
153
  { style: { display: "flex", justifyContent: "space-between", marginBottom: 8 } },
143
154
  React.createElement("strong", null, "Sisyphus \u7F16\u6392"),
144
- React.createElement("button", { onClick: () => setOpen(false) }, "\xD7")
155
+ React.createElement("button", { onClick: () => {
156
+ panelOpen = false;
157
+ emit();
158
+ } }, "\xD7")
145
159
  ),
146
160
  React.createElement(
147
161
  "div",
148
162
  { style: { marginBottom: 8 } },
149
163
  React.createElement("div", { style: { fontWeight: 600, marginBottom: 4 } }, "\u8FD0\u884C\u4E2D"),
150
- current ? node(current.agentType ?? "?", statusGlyph(current.status), current.childId, () => current.childId && jump(current.childId)) : React.createElement("div", { style: { color: "#888" } }, "\u25CB \u7A7A\u95F2")
164
+ current ? node(typeLabel(current.agentType), statusGlyph(current.status), current.childId, () => current.childId && jump(current.childId)) : React.createElement("div", { style: { color: "#888" } }, "\u25CB \u7A7A\u95F2")
151
165
  ),
152
166
  React.createElement(
153
167
  "div",
154
168
  { style: { marginBottom: 8 } },
155
169
  React.createElement("div", { style: { fontWeight: 600, marginBottom: 4 } }, `\u961F\u5217 (${s.queue.length})`),
156
- s.queue.map((w) => node(String(w.agentType ?? "?"), "\u23F3"))
170
+ s.queue.map((w) => node(typeLabel(w.agentType), "\u23F3"))
157
171
  ),
158
172
  React.createElement(
159
173
  "div",
160
174
  { style: { marginBottom: 8 } },
161
175
  React.createElement("div", { style: { fontWeight: 600, marginBottom: 4 } }, `\u6C42\u52A9 (${s.helpRequests.length})`),
162
- s.helpRequests.map((h) => node(`[${h.intent ?? "?"}]`, "\u2753", h.childId, () => h.childId && jump(h.childId)))
176
+ s.helpRequests.map((h) => node(`[${intentLabel(h.intent)}]`, "\u2753", h.childId, () => h.childId && jump(h.childId)))
163
177
  ),
164
178
  React.createElement(
165
179
  "div",
@@ -167,7 +181,7 @@ function apply(ctx) {
167
181
  React.createElement("div", { style: { fontWeight: 600, marginBottom: 4 } }, `\u5386\u53F2 (${s.history.length})`),
168
182
  s.history.slice(-8).map((r) => {
169
183
  const rec = r;
170
- return node(`${rec.agentType ?? "?"} \u2014 ${String(rec.conclusion ?? "").replace(/\s+/g, " ").slice(0, 60)}`, statusGlyph(rec.status), rec.childId, () => rec.childId && jump(rec.childId));
184
+ return node(`${typeLabel(rec.agentType)} \u2014 ${String(rec.conclusion ?? "").replace(/\s+/g, " ").slice(0, 60)}`, statusGlyph(rec.status), rec.childId, () => rec.childId && jump(rec.childId));
171
185
  })
172
186
  )
173
187
  );
@@ -201,9 +215,9 @@ function apply(ctx) {
201
215
  if (!sp) return;
202
216
  if (connection && connection.rpc && typeof connection.rpc.call === "function") {
203
217
  connection.rpc.call("/dsh-my-go", "loadSettings", {}).then((res) => {
204
- if (res && res.ok && res.value) setDraft(res.value);
205
- else setDraft({});
206
- }).catch(() => setDraft({}));
218
+ if (res && res.ok) setDraft(res.value ?? {});
219
+ else setDraft(null);
220
+ }).catch(() => setDraft(null));
207
221
  connection.rpc.call("/dsh-my-go", "listModels", {}).then((res) => {
208
222
  if (res && res.ok && res.value && Array.isArray(res.value.providers)) setAvailable(res.value);
209
223
  }).catch(() => {
@@ -225,6 +239,10 @@ function apply(ctx) {
225
239
  });
226
240
  };
227
241
  const save = async () => {
242
+ if (!draft) {
243
+ setMsg("\u914D\u7F6E\u5C1A\u672A\u52A0\u8F7D\u6210\u529F\uFF0C\u5DF2\u7981\u6B62\u4FDD\u5B58\u4EE5\u907F\u514D\u8986\u76D6");
244
+ return;
245
+ }
228
246
  setSaving(true);
229
247
  setMsg(null);
230
248
  try {
@@ -251,9 +269,9 @@ function apply(ctx) {
251
269
  const rowStyle = { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8, marginBottom: 8 };
252
270
  const EFFORTS = ["", "low", "high", "max"];
253
271
  const providers = available.providers;
254
- const providerLabel = (v) => v === "" ? "\u8DDF\u968F Sisyphus" : v;
255
- const modelLabel = (v) => v === "" ? "\u8DDF\u968F Sisyphus" : v;
256
- const effortLabel = (v) => v === "" ? "\u8DDF\u968F\u6A21\u578B\u9ED8\u8BA4" : v;
272
+ const providerLabel = (v) => v === "" ? "\u8DDF\u968F Sisyphus\uFF08\u5BF9\u8BDD\u6846\u6240\u9009\u6A21\u578B\uFF09" : v;
273
+ const modelLabel = (v) => v === "" ? "\u8DDF\u968F Sisyphus\uFF08\u5BF9\u8BDD\u6846\u6240\u9009\u6A21\u578B\uFF09" : v;
274
+ const effortLabel = (v) => v === "" ? "\u8DDF\u968F\u6A21\u578B\u9ED8\u8BA4" : { low: "\u4F4E\uFF08low\uFF09", high: "\u9AD8\uFF08high\uFF09", max: "\u6700\u9AD8\uFF08max\uFF09" }[v] ?? v;
257
275
  const makeSelect = (value, options, labelFn, onChange) => React.createElement(
258
276
  "select",
259
277
  { style: selectStyle, value: value ?? "", onChange: (e) => onChange(e.target.value) },
@@ -271,7 +289,8 @@ function apply(ctx) {
271
289
  "div",
272
290
  { style: { padding: 16, maxWidth: 600 } },
273
291
  React.createElement("h2", { style: { margin: "0 0 4px" } }, "MyGO \u7F16\u6392\u914D\u7F6E"),
274
- React.createElement("p", { style: { margin: "0 0 16px", fontSize: 13, color: "var(--text-secondary, #888)" } }, "\u6BCF\u4E2A\u5B50\u667A\u80FD\u4F53\u7684\u6A21\u578B / Provider / \u601D\u8003\u7A0B\u5EA6 / DSV4P0813 \u8865\u4E01\u5F00\u5173\u3002\u4FEE\u6539\u540E\u70B9\u4FDD\u5B58\uFF0C\u4E0B\u6B21\u6D3E\u53D1\u751F\u6548\u3002"),
292
+ React.createElement("p", { style: { margin: "0 0 6px", fontSize: 13, color: "var(--text-secondary, #888)" } }, "\u7ED9\u6BCF\u4E2A\u5DE5\u79CD\u5355\u72EC\u6307\u5B9A\u6A21\u578B\u3002\u7559\u7A7A = \u8DDF\u968F Sisyphus\uFF08\u5373\u60A8\u5728\u5BF9\u8BDD\u6846\u91CC\u9009\u7684\u6A21\u578B\uFF09\uFF1B\u6539\u5B8C\u70B9\u300C\u7ACB\u5373\u4FDD\u5B58\u300D\uFF0C\u4E0B\u6B21\u6D3E\u53D1\u751F\u6548\u3002"),
293
+ React.createElement("p", { style: { margin: "0 0 16px", fontSize: 12, color: "var(--text-secondary, #888)" } }, "\u5B57\u6BB5\u8BF4\u660E\uFF1A\u6E20\u9053 = \u6A21\u578B\u4ECE\u54EA\u4E2A\u7F51\u5173/\u8D26\u53F7\u8D70\uFF1B\u601D\u8003\u6863\u4F4D = \u63A8\u7406\u5F3A\u5EA6\uFF08\u8D8A\u9AD8\u8D8A\u8D35\u8D8A\u806A\u660E\uFF09\uFF1BDSV4P0813 \u8865\u4E01 = \u4E24\u9636\u6BB5\u951A\u5B9A\u4E0A\u4E0B\u6587\u6CE8\u5165\uFF0C\u4E13\u95E8\u538B\u69A8 DeepSeek V4 Pro 0813 \u7684\u5B9E\u529B\uFF0C\u5176\u4ED6\u6A21\u578B\u522B\u5F00\u3002"),
275
294
  fetchFailed ? React.createElement("div", {
276
295
  style: { padding: 12, marginBottom: 16, borderRadius: 6, background: "rgba(244,67,54,0.1)", border: "1px solid rgba(244,67,54,0.3)", fontSize: 13 }
277
296
  }, "\u26A0 \u65E0\u6CD5\u4ECE DSH \u83B7\u53D6 Provider/Model \u5217\u8868\u3002\u8BF7\u786E\u8BA4\uFF1A1) \u5DF2\u91CD\u542F dsh web\uFF1B2) LLM \u63D2\u4EF6\u5DF2\u914D\u7F6E\u5E76\u6FC0\u6D3B\u3002\u4E0B\u62C9\u6846\u4ECD\u53EF\u624B\u52A8\u8F93\u5165\u81EA\u5B9A\u4E49\u503C\u3002") : null,
@@ -287,13 +306,13 @@ function apply(ctx) {
287
306
  React.createElement(
288
307
  "div",
289
308
  null,
290
- React.createElement("div", { style: labelStyle }, "Provider"),
309
+ React.createElement("div", { style: labelStyle }, "\u6E20\u9053\uFF08Provider\uFF09"),
291
310
  makeSelect(cfg.provider ?? "", ["", ...providers], providerLabel, (v) => set(type, "provider", v))
292
311
  ),
293
312
  React.createElement(
294
313
  "div",
295
314
  null,
296
- React.createElement("div", { style: labelStyle }, "Model"),
315
+ React.createElement("div", { style: labelStyle }, "\u6A21\u578B\uFF08Model\uFF09"),
297
316
  makeSelect(cfg.model ?? "", ["", ...modelsForProvider(cfg.provider ?? "")], modelLabel, (v) => set(type, "model", v))
298
317
  )
299
318
  ),
@@ -303,7 +322,7 @@ function apply(ctx) {
303
322
  React.createElement(
304
323
  "div",
305
324
  null,
306
- React.createElement("div", { style: labelStyle }, "Reasoning Effort"),
325
+ React.createElement("div", { style: labelStyle }, "\u601D\u8003\u6863\u4F4D\uFF08Reasoning Effort\uFF09"),
307
326
  makeSelect(cfg.reasoningEffort ?? "", EFFORTS, effortLabel, (v) => set(type, "reasoningEffort", v))
308
327
  ),
309
328
  React.createElement(
@@ -313,7 +332,7 @@ function apply(ctx) {
313
332
  "label",
314
333
  { style: { display: "flex", alignItems: "center", gap: 6, cursor: "pointer", fontSize: 13, paddingTop: 18 } },
315
334
  React.createElement("input", { type: "checkbox", checked: cfg.dsv4p0813 === true, onChange: (e) => set(type, "dsv4p0813", e.target.checked) }),
316
- "DSV4P0813"
335
+ "DSV4P0813 \u8865\u4E01"
317
336
  )
318
337
  )
319
338
  )
@@ -324,7 +343,7 @@ function apply(ctx) {
324
343
  { style: { display: "flex", alignItems: "center", gap: 12, marginTop: 8 } },
325
344
  React.createElement("button", {
326
345
  onClick: save,
327
- disabled: saving,
346
+ disabled: saving || !draft,
328
347
  style: { padding: "6px 20px", borderRadius: 6, border: "1px solid var(--separator, #333)", background: "transparent", color: "var(--text, #e0e0e0)", cursor: saving ? "wait" : "pointer", fontSize: 13 }
329
348
  }, saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u7ACB\u5373\u4FDD\u5B58"),
330
349
  msg ? React.createElement("span", { style: { fontSize: 13, color: msg.startsWith("\u5DF2") ? "#4caf50" : "#f44336" } }, msg) : null
@@ -352,7 +371,14 @@ function apply(ctx) {
352
371
  }
353
372
  }
354
373
  } else if (!current && lastJumpedTo && sessions) {
374
+ const parentSessionId = snapshot.parentSessionId;
355
375
  lastJumpedTo = null;
376
+ if (parentSessionId && typeof sessions.open === "function") {
377
+ try {
378
+ sessions.open(parentSessionId);
379
+ } catch {
380
+ }
381
+ }
356
382
  }
357
383
  }, 800) : void 0;
358
384
  return () => {
package/dist/client.js CHANGED
@@ -44,7 +44,19 @@ var React = __toESM(require("react"), 1);
44
44
  var name = "dsh-my-go";
45
45
  var inject = ["slots", "settingsScope", "connection"];
46
46
  var AGENT_TYPES = ["sisyphus", "hermes", "explore", "librarian", "looker", "hephaestus", "prometheus", "oracle"];
47
- var AGENT_LABELS = { sisyphus: "Sisyphus", hermes: "Hermes", explore: "Explore", librarian: "Librarian", looker: "Looker", hephaestus: "Hephaestus", prometheus: "Prometheus", oracle: "Oracle" };
47
+ var AGENT_LABELS = {
48
+ sisyphus: "\u603B\u8C03\u5EA6\xB7\u8D28\u68C0 Sisyphus",
49
+ hermes: "\u5FEB\u901F\u6267\u884C Hermes",
50
+ explore: "\u5FEB\u901F\u68C0\u7D22 Explore",
51
+ librarian: "\u6587\u6863\u67E5\u8BE2 Librarian",
52
+ looker: "\u591A\u6A21\u6001\u770B\u56FE Looker",
53
+ hephaestus: "\u4EE3\u7801\u7F16\u5199 Hephaestus",
54
+ prometheus: "\u9700\u6C42\u89C4\u5212 Prometheus",
55
+ oracle: "\u7591\u96BE\u515C\u5E95\xB7\u7EC8\u9A8C Oracle"
56
+ };
57
+ var typeLabel = (t) => AGENT_LABELS[t] ?? String(t ?? "?");
58
+ var INTENT_LABELS = { explore: "\u68C0\u7D22", read_doc: "\u67E5\u6587\u6863", look_image: "\u770B\u56FE", replan: "\u8BF7\u6C42\u6362\u5DE5\u79CD", execute: "\u8BF7\u6C42\u4EE3\u6267\u884C", ask_user: "\u8BF7\u6C42\u95EE\u7528\u6237" };
59
+ var intentLabel = (i) => INTENT_LABELS[i] ?? String(i ?? "?");
48
60
  function apply(ctx) {
49
61
  const client = ctx;
50
62
  const slots = client.get("slots");
@@ -98,14 +110,13 @@ function apply(ctx) {
98
110
  }
99
111
  }
100
112
  function TreePanel(_props) {
101
- const [open, setOpen] = React.useState(panelOpen);
102
113
  const [, force] = React.useState(0);
103
114
  React.useEffect(() => {
104
- const unsub2 = () => listeners.delete(force);
105
- listeners.add(force);
106
- return unsub2;
115
+ const rerender = () => force((c) => c + 1);
116
+ listeners.add(rerender);
117
+ return () => listeners.delete(rerender);
107
118
  }, []);
108
- if (!open) return null;
119
+ if (!panelOpen) return null;
109
120
  const s = snapshot;
110
121
  const node = (label, status, childId, onClick) => React.createElement(
111
122
  "div",
@@ -119,7 +130,7 @@ function apply(ctx) {
119
130
  );
120
131
  const jump = (childId) => {
121
132
  if (sessions && typeof sessions.openSubagent === "function") {
122
- sessions.openSubagent({ parentSessionId: "", childSessionId: childId, mode: "continuable" });
133
+ sessions.openSubagent({ parentSessionId: snapshot.parentSessionId ?? "", childSessionId: childId, mode: "continuable" });
123
134
  }
124
135
  };
125
136
  const current = s.current;
@@ -146,25 +157,28 @@ function apply(ctx) {
146
157
  "div",
147
158
  { style: { display: "flex", justifyContent: "space-between", marginBottom: 8 } },
148
159
  React.createElement("strong", null, "Sisyphus \u7F16\u6392"),
149
- React.createElement("button", { onClick: () => setOpen(false) }, "\xD7")
160
+ React.createElement("button", { onClick: () => {
161
+ panelOpen = false;
162
+ emit();
163
+ } }, "\xD7")
150
164
  ),
151
165
  React.createElement(
152
166
  "div",
153
167
  { style: { marginBottom: 8 } },
154
168
  React.createElement("div", { style: { fontWeight: 600, marginBottom: 4 } }, "\u8FD0\u884C\u4E2D"),
155
- current ? node(current.agentType ?? "?", statusGlyph(current.status), current.childId, () => current.childId && jump(current.childId)) : React.createElement("div", { style: { color: "#888" } }, "\u25CB \u7A7A\u95F2")
169
+ current ? node(typeLabel(current.agentType), statusGlyph(current.status), current.childId, () => current.childId && jump(current.childId)) : React.createElement("div", { style: { color: "#888" } }, "\u25CB \u7A7A\u95F2")
156
170
  ),
157
171
  React.createElement(
158
172
  "div",
159
173
  { style: { marginBottom: 8 } },
160
174
  React.createElement("div", { style: { fontWeight: 600, marginBottom: 4 } }, `\u961F\u5217 (${s.queue.length})`),
161
- s.queue.map((w) => node(String(w.agentType ?? "?"), "\u23F3"))
175
+ s.queue.map((w) => node(typeLabel(w.agentType), "\u23F3"))
162
176
  ),
163
177
  React.createElement(
164
178
  "div",
165
179
  { style: { marginBottom: 8 } },
166
180
  React.createElement("div", { style: { fontWeight: 600, marginBottom: 4 } }, `\u6C42\u52A9 (${s.helpRequests.length})`),
167
- s.helpRequests.map((h) => node(`[${h.intent ?? "?"}]`, "\u2753", h.childId, () => h.childId && jump(h.childId)))
181
+ s.helpRequests.map((h) => node(`[${intentLabel(h.intent)}]`, "\u2753", h.childId, () => h.childId && jump(h.childId)))
168
182
  ),
169
183
  React.createElement(
170
184
  "div",
@@ -172,7 +186,7 @@ function apply(ctx) {
172
186
  React.createElement("div", { style: { fontWeight: 600, marginBottom: 4 } }, `\u5386\u53F2 (${s.history.length})`),
173
187
  s.history.slice(-8).map((r) => {
174
188
  const rec = r;
175
- return node(`${rec.agentType ?? "?"} \u2014 ${String(rec.conclusion ?? "").replace(/\s+/g, " ").slice(0, 60)}`, statusGlyph(rec.status), rec.childId, () => rec.childId && jump(rec.childId));
189
+ return node(`${typeLabel(rec.agentType)} \u2014 ${String(rec.conclusion ?? "").replace(/\s+/g, " ").slice(0, 60)}`, statusGlyph(rec.status), rec.childId, () => rec.childId && jump(rec.childId));
176
190
  })
177
191
  )
178
192
  );
@@ -206,9 +220,9 @@ function apply(ctx) {
206
220
  if (!sp) return;
207
221
  if (connection && connection.rpc && typeof connection.rpc.call === "function") {
208
222
  connection.rpc.call("/dsh-my-go", "loadSettings", {}).then((res) => {
209
- if (res && res.ok && res.value) setDraft(res.value);
210
- else setDraft({});
211
- }).catch(() => setDraft({}));
223
+ if (res && res.ok) setDraft(res.value ?? {});
224
+ else setDraft(null);
225
+ }).catch(() => setDraft(null));
212
226
  connection.rpc.call("/dsh-my-go", "listModels", {}).then((res) => {
213
227
  if (res && res.ok && res.value && Array.isArray(res.value.providers)) setAvailable(res.value);
214
228
  }).catch(() => {
@@ -230,6 +244,10 @@ function apply(ctx) {
230
244
  });
231
245
  };
232
246
  const save = async () => {
247
+ if (!draft) {
248
+ setMsg("\u914D\u7F6E\u5C1A\u672A\u52A0\u8F7D\u6210\u529F\uFF0C\u5DF2\u7981\u6B62\u4FDD\u5B58\u4EE5\u907F\u514D\u8986\u76D6");
249
+ return;
250
+ }
233
251
  setSaving(true);
234
252
  setMsg(null);
235
253
  try {
@@ -256,9 +274,9 @@ function apply(ctx) {
256
274
  const rowStyle = { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8, marginBottom: 8 };
257
275
  const EFFORTS = ["", "low", "high", "max"];
258
276
  const providers = available.providers;
259
- const providerLabel = (v) => v === "" ? "\u8DDF\u968F Sisyphus" : v;
260
- const modelLabel = (v) => v === "" ? "\u8DDF\u968F Sisyphus" : v;
261
- const effortLabel = (v) => v === "" ? "\u8DDF\u968F\u6A21\u578B\u9ED8\u8BA4" : v;
277
+ const providerLabel = (v) => v === "" ? "\u8DDF\u968F Sisyphus\uFF08\u5BF9\u8BDD\u6846\u6240\u9009\u6A21\u578B\uFF09" : v;
278
+ const modelLabel = (v) => v === "" ? "\u8DDF\u968F Sisyphus\uFF08\u5BF9\u8BDD\u6846\u6240\u9009\u6A21\u578B\uFF09" : v;
279
+ const effortLabel = (v) => v === "" ? "\u8DDF\u968F\u6A21\u578B\u9ED8\u8BA4" : { low: "\u4F4E\uFF08low\uFF09", high: "\u9AD8\uFF08high\uFF09", max: "\u6700\u9AD8\uFF08max\uFF09" }[v] ?? v;
262
280
  const makeSelect = (value, options, labelFn, onChange) => React.createElement(
263
281
  "select",
264
282
  { style: selectStyle, value: value ?? "", onChange: (e) => onChange(e.target.value) },
@@ -276,7 +294,8 @@ function apply(ctx) {
276
294
  "div",
277
295
  { style: { padding: 16, maxWidth: 600 } },
278
296
  React.createElement("h2", { style: { margin: "0 0 4px" } }, "MyGO \u7F16\u6392\u914D\u7F6E"),
279
- React.createElement("p", { style: { margin: "0 0 16px", fontSize: 13, color: "var(--text-secondary, #888)" } }, "\u6BCF\u4E2A\u5B50\u667A\u80FD\u4F53\u7684\u6A21\u578B / Provider / \u601D\u8003\u7A0B\u5EA6 / DSV4P0813 \u8865\u4E01\u5F00\u5173\u3002\u4FEE\u6539\u540E\u70B9\u4FDD\u5B58\uFF0C\u4E0B\u6B21\u6D3E\u53D1\u751F\u6548\u3002"),
297
+ React.createElement("p", { style: { margin: "0 0 6px", fontSize: 13, color: "var(--text-secondary, #888)" } }, "\u7ED9\u6BCF\u4E2A\u5DE5\u79CD\u5355\u72EC\u6307\u5B9A\u6A21\u578B\u3002\u7559\u7A7A = \u8DDF\u968F Sisyphus\uFF08\u5373\u60A8\u5728\u5BF9\u8BDD\u6846\u91CC\u9009\u7684\u6A21\u578B\uFF09\uFF1B\u6539\u5B8C\u70B9\u300C\u7ACB\u5373\u4FDD\u5B58\u300D\uFF0C\u4E0B\u6B21\u6D3E\u53D1\u751F\u6548\u3002"),
298
+ React.createElement("p", { style: { margin: "0 0 16px", fontSize: 12, color: "var(--text-secondary, #888)" } }, "\u5B57\u6BB5\u8BF4\u660E\uFF1A\u6E20\u9053 = \u6A21\u578B\u4ECE\u54EA\u4E2A\u7F51\u5173/\u8D26\u53F7\u8D70\uFF1B\u601D\u8003\u6863\u4F4D = \u63A8\u7406\u5F3A\u5EA6\uFF08\u8D8A\u9AD8\u8D8A\u8D35\u8D8A\u806A\u660E\uFF09\uFF1BDSV4P0813 \u8865\u4E01 = \u4E24\u9636\u6BB5\u951A\u5B9A\u4E0A\u4E0B\u6587\u6CE8\u5165\uFF0C\u4E13\u95E8\u538B\u69A8 DeepSeek V4 Pro 0813 \u7684\u5B9E\u529B\uFF0C\u5176\u4ED6\u6A21\u578B\u522B\u5F00\u3002"),
280
299
  fetchFailed ? React.createElement("div", {
281
300
  style: { padding: 12, marginBottom: 16, borderRadius: 6, background: "rgba(244,67,54,0.1)", border: "1px solid rgba(244,67,54,0.3)", fontSize: 13 }
282
301
  }, "\u26A0 \u65E0\u6CD5\u4ECE DSH \u83B7\u53D6 Provider/Model \u5217\u8868\u3002\u8BF7\u786E\u8BA4\uFF1A1) \u5DF2\u91CD\u542F dsh web\uFF1B2) LLM \u63D2\u4EF6\u5DF2\u914D\u7F6E\u5E76\u6FC0\u6D3B\u3002\u4E0B\u62C9\u6846\u4ECD\u53EF\u624B\u52A8\u8F93\u5165\u81EA\u5B9A\u4E49\u503C\u3002") : null,
@@ -292,13 +311,13 @@ function apply(ctx) {
292
311
  React.createElement(
293
312
  "div",
294
313
  null,
295
- React.createElement("div", { style: labelStyle }, "Provider"),
314
+ React.createElement("div", { style: labelStyle }, "\u6E20\u9053\uFF08Provider\uFF09"),
296
315
  makeSelect(cfg.provider ?? "", ["", ...providers], providerLabel, (v) => set(type, "provider", v))
297
316
  ),
298
317
  React.createElement(
299
318
  "div",
300
319
  null,
301
- React.createElement("div", { style: labelStyle }, "Model"),
320
+ React.createElement("div", { style: labelStyle }, "\u6A21\u578B\uFF08Model\uFF09"),
302
321
  makeSelect(cfg.model ?? "", ["", ...modelsForProvider(cfg.provider ?? "")], modelLabel, (v) => set(type, "model", v))
303
322
  )
304
323
  ),
@@ -308,7 +327,7 @@ function apply(ctx) {
308
327
  React.createElement(
309
328
  "div",
310
329
  null,
311
- React.createElement("div", { style: labelStyle }, "Reasoning Effort"),
330
+ React.createElement("div", { style: labelStyle }, "\u601D\u8003\u6863\u4F4D\uFF08Reasoning Effort\uFF09"),
312
331
  makeSelect(cfg.reasoningEffort ?? "", EFFORTS, effortLabel, (v) => set(type, "reasoningEffort", v))
313
332
  ),
314
333
  React.createElement(
@@ -318,7 +337,7 @@ function apply(ctx) {
318
337
  "label",
319
338
  { style: { display: "flex", alignItems: "center", gap: 6, cursor: "pointer", fontSize: 13, paddingTop: 18 } },
320
339
  React.createElement("input", { type: "checkbox", checked: cfg.dsv4p0813 === true, onChange: (e) => set(type, "dsv4p0813", e.target.checked) }),
321
- "DSV4P0813"
340
+ "DSV4P0813 \u8865\u4E01"
322
341
  )
323
342
  )
324
343
  )
@@ -329,7 +348,7 @@ function apply(ctx) {
329
348
  { style: { display: "flex", alignItems: "center", gap: 12, marginTop: 8 } },
330
349
  React.createElement("button", {
331
350
  onClick: save,
332
- disabled: saving,
351
+ disabled: saving || !draft,
333
352
  style: { padding: "6px 20px", borderRadius: 6, border: "1px solid var(--separator, #333)", background: "transparent", color: "var(--text, #e0e0e0)", cursor: saving ? "wait" : "pointer", fontSize: 13 }
334
353
  }, saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u7ACB\u5373\u4FDD\u5B58"),
335
354
  msg ? React.createElement("span", { style: { fontSize: 13, color: msg.startsWith("\u5DF2") ? "#4caf50" : "#f44336" } }, msg) : null
@@ -357,7 +376,14 @@ function apply(ctx) {
357
376
  }
358
377
  }
359
378
  } else if (!current && lastJumpedTo && sessions) {
379
+ const parentSessionId = snapshot.parentSessionId;
360
380
  lastJumpedTo = null;
381
+ if (parentSessionId && typeof sessions.open === "function") {
382
+ try {
383
+ sessions.open(parentSessionId);
384
+ } catch {
385
+ }
386
+ }
361
387
  }
362
388
  }, 800) : void 0;
363
389
  return () => {
@@ -60,11 +60,13 @@ interface OrchestrationState {
60
60
 
61
61
  - `go_work` 在已有运行子智能体时进入队列,返回排队提示;子智能体结束
62
62
  (`subagent/end`)后自动启动队首。
63
- - `need_help` 挂起当前子智能体(通过 `interrupt` + 状态标记 waiting),
64
- 记录 helpRequestId 注入 Sisyphus。其中 `intent=execute` 用于子智能体被沙箱/权限拒绝时,
63
+ - `need_help` 挂起当前子智能体(状态机标记 waiting + 工具描述约定「调用后停止」;
64
+ 注意:当前为台账层挂起,无强制 interrupt,子智能体若在返回后继续行动靠
65
+ prompt 约束兜底),记录 helpRequestId 注入 Sisyphus。其中 `intent=execute` 用于子智能体被沙箱/权限拒绝时,
65
66
  将待执行的具体指令发给 Sisyphus 代为执行。`intent=ask_user` 用于子智能体需要向用户
66
67
  提问澄清需求时,将问题清单发给 Sisyphus 代为转达给用户,拿到答案后续回请求者。
67
- - `continue` 唤醒挂起/已结束的子智能体(`followup`)。
68
+ - `continue` 唤醒挂起/已结束的子智能体(`followup`);对已结束的子智能体会
69
+ 重新入册(revive 回 currentMap + 恢复类型登记),保持单线阻塞与结论回收。
68
70
 
69
71
  ### 2.2 模型与 effort 绑定
70
72
 
@@ -77,8 +79,9 @@ interface OrchestrationState {
77
79
  `reasoningEffort`(以及兜底 provider/model)。类型识别通过会话 label
78
80
  前缀约定:`dsh-my-go:<agentType>`。
79
81
 
80
- > ⚠️ effort 档位需按适配器能力表映射(deepseek-official off/high/max,
81
- > `low` 会报错)。broker 提供映射:low→high 兼容。
82
+ > ⚠️ effort 档位跟随 DSH 模型目录:仅在目标模型实际支持所配档位时才设置;
83
+ > 不支持或能力未知时**不设置**(走适配器默认),拒绝硬映射/钳位
84
+ > (如 deepseek-official 仅 off/high/max,配 `low` 则留空而不是改成 high)。
82
85
 
83
86
  ### 2.3 DSV4P0813 补丁(参考 tmp/liangshen)
84
87
 
@@ -87,8 +90,9 @@ DSV4P0813 需要「两阶段锚定」上下文注入流程才能发挥全部能
87
90
  - **Phase 1(未锚定)**:子智能体只见最小工具集 + 单行 persona +
88
91
  白名单消息源(user/goal),锚定 minimal 推理轨迹(首块含 `we` 且无
89
92
  `let me`)。
90
- - **晋升**:首块锚定后放开完整工具目录与全部 prompt section
91
- compaction 后回落受控阶段。
93
+ - **晋升**:首块锚定后放开完整工具目录与全部 prompt section
94
+ (注:「compaction 后回落受控阶段」尚未实现——晋升状态目前一经提升
95
+ 不回落。)
92
96
 
93
97
  broker 为每个智能体提供 `dsv4p0813: boolean` 开关。开启时给该子智能体
94
98
  注入阶段化引导(复用 liangshen 的 tool-bootstrap 语义,按子智能体类型
@@ -96,8 +100,9 @@ broker 为每个智能体提供 `dsv4p0813: boolean` 开关。开启时给该子
96
100
 
97
101
  ## 3. UI 适配
98
102
 
99
- - **details 右侧详情栏**:树状图显示子 Agent 运行情况(current / waiting /
100
- queue / done),点击节点可跳转子会话。
103
+ - **overlay 树状图面板**:`shell.overlay` 浮层显示子 Agent 运行情况
104
+ (current / queue / help / history),由侧栏底部 🧭 按钮开关,
105
+ 点击节点可跳转子会话(经 host 半的 connection.rpc 快照桥轮询)。
101
106
  - **自动跳转**:子智能体运行时,client 通过 `sessions.openSubagent({
102
107
  parentSessionId, childSessionId, mode: 'continuable' })` 自动跳转到子会话,
103
108
  展示其上下文;子智能体结束(`subagent/end`)后跳回 Sisyphus 父会话。