dsh-my-go 0.1.2 → 0.1.4

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.
@@ -37,7 +37,9 @@ __export(client_exports, {
37
37
  module.exports = __toCommonJS(client_exports);
38
38
  var React = __toESM(require("react"), 1);
39
39
  var name = "dsh-my-go";
40
- var inject = ["slots"];
40
+ var inject = ["slots", "settingsScope"];
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" };
41
43
  function apply(ctx) {
42
44
  const client = ctx;
43
45
  const slots = client.get("slots");
@@ -182,17 +184,102 @@ function apply(ctx) {
182
184
  style: { width: props && props.wide ? "100%" : 32, height: 32, border: "none", background: "transparent", cursor: "pointer" }
183
185
  }, "\u{1F9ED}")
184
186
  ));
187
+ const scope = client.get("settingsScope") ? client.get("settingsScope").bind({ namespace: "dsh-my-go" }) : null;
185
188
  slots.inject("settings.section", () => slots.register(
186
189
  { name: "settings.section", id: "dsh-my-go", order: 30, label: "MyGO \u7F16\u6392" },
187
- (props) => React.createElement(SettingsPage, props)
190
+ (props) => React.createElement(SettingsPage, { ...props, scope })
188
191
  ));
189
- function SettingsPage(_props) {
192
+ function SettingsPage({ scope: sp, close }) {
193
+ const [draft, setDraft] = React.useState(null);
194
+ const [saving, setSaving] = React.useState(false);
195
+ const [msg, setMsg] = React.useState(null);
196
+ React.useEffect(() => {
197
+ if (!sp) return;
198
+ try {
199
+ setDraft(sp.read());
200
+ } catch {
201
+ setDraft({});
202
+ }
203
+ }, [sp]);
204
+ if (!sp) return React.createElement("div", { style: { padding: 16, color: "#888" } }, "\u8BBE\u7F6E\u670D\u52A1\u4E0D\u53EF\u7528");
205
+ const set = (type, field, value) => {
206
+ setDraft((prev) => ({ ...prev, [type]: { ...prev?.[type], [field]: value } }));
207
+ };
208
+ const save = async () => {
209
+ setSaving(true);
210
+ setMsg(null);
211
+ try {
212
+ await sp.update(draft);
213
+ setMsg("\u5DF2\u4FDD\u5B58");
214
+ } catch (e) {
215
+ setMsg("\u4FDD\u5B58\u5931\u8D25: " + String(e));
216
+ } finally {
217
+ setSaving(false);
218
+ }
219
+ };
220
+ const inputStyle = { background: "var(--surface, #1e1e1e)", color: "var(--text, #e0e0e0)", border: "1px solid var(--separator, #333)", borderRadius: 4, padding: "4px 8px", fontSize: 13, width: "100%", boxSizing: "border-box" };
221
+ const labelStyle = { fontSize: 12, color: "var(--text-secondary, #888)", marginBottom: 2 };
222
+ const cardStyle = { border: "1px solid var(--separator, #333)", borderRadius: 8, padding: 12, marginBottom: 12 };
223
+ const rowStyle = { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8, marginBottom: 8 };
190
224
  return React.createElement(
191
225
  "div",
192
- { style: { padding: 16 } },
193
- React.createElement("h2", null, "MyGO \u7F16\u6392\u914D\u7F6E"),
194
- React.createElement("p", null, "\u6BCF\u4E2A\u5B50\u667A\u80FD\u4F53\u7684\u6A21\u578B / \u601D\u8003\u7A0B\u5EA6 / DSV4P0813 \u8865\u4E01\u5F00\u5173\u3002\u4FEE\u6539\u540E\u901A\u8FC7 Settings \u670D\u52A1\u6301\u4E45\u5316\u3002"),
195
- React.createElement("div", { style: { color: "#888", marginTop: 12 } }, "\u914D\u7F6E\u9879\u7531 host \u4FA7 settings \u547D\u540D\u7A7A\u95F4 dsh-my-go \u63D0\u4F9B\uFF1B\u4FEE\u6539\u540E\u751F\u6548\u4E8E\u4E0B\u4E00\u6B21\u6D3E\u53D1\u3002")
226
+ { style: { padding: 16, maxWidth: 600 } },
227
+ React.createElement("h2", { style: { margin: "0 0 4px" } }, "MyGO \u7F16\u6392\u914D\u7F6E"),
228
+ 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"),
229
+ ...AGENT_TYPES.map((type) => {
230
+ const cfg = draft?.[type] || {};
231
+ return React.createElement(
232
+ "div",
233
+ { key: type, style: cardStyle },
234
+ React.createElement("div", { style: { fontWeight: 600, marginBottom: 8 } }, AGENT_LABELS[type] || type),
235
+ React.createElement(
236
+ "div",
237
+ { style: rowStyle },
238
+ React.createElement(
239
+ "div",
240
+ null,
241
+ React.createElement("div", { style: labelStyle }, "Provider"),
242
+ React.createElement("input", { style: inputStyle, value: cfg.provider ?? "", placeholder: "\u7559\u7A7A\u8DDF\u968F Sisyphus", onChange: (e) => set(type, "provider", e.target.value) })
243
+ ),
244
+ React.createElement(
245
+ "div",
246
+ null,
247
+ React.createElement("div", { style: labelStyle }, "Model"),
248
+ React.createElement("input", { style: inputStyle, value: cfg.model ?? "", placeholder: "\u7559\u7A7A\u8DDF\u968F Sisyphus", onChange: (e) => set(type, "model", e.target.value) })
249
+ )
250
+ ),
251
+ React.createElement(
252
+ "div",
253
+ { style: rowStyle },
254
+ React.createElement(
255
+ "div",
256
+ null,
257
+ React.createElement("div", { style: labelStyle }, "Reasoning Effort"),
258
+ React.createElement("input", { style: inputStyle, value: cfg.reasoningEffort ?? "", placeholder: "low / high / max", onChange: (e) => set(type, "reasoningEffort", e.target.value) })
259
+ ),
260
+ React.createElement(
261
+ "div",
262
+ { style: { display: "flex", alignItems: "flex-end", gap: 8 } },
263
+ React.createElement(
264
+ "label",
265
+ { style: { display: "flex", alignItems: "center", gap: 6, cursor: "pointer", fontSize: 13, paddingTop: 18 } },
266
+ React.createElement("input", { type: "checkbox", checked: cfg.dsv4p0813 === true, onChange: (e) => set(type, "dsv4p0813", e.target.checked) }),
267
+ "DSV4P0813"
268
+ )
269
+ )
270
+ )
271
+ );
272
+ }),
273
+ React.createElement(
274
+ "div",
275
+ { style: { display: "flex", alignItems: "center", gap: 12, marginTop: 8 } },
276
+ React.createElement("button", {
277
+ onClick: save,
278
+ disabled: saving,
279
+ style: { padding: "6px 20px", borderRadius: 6, border: "none", background: "var(--brand, #0066ff)", color: "#fff", cursor: saving ? "wait" : "pointer", fontSize: 14 }
280
+ }, saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58"),
281
+ msg ? React.createElement("span", { style: { fontSize: 13, color: msg.startsWith("\u5DF2") ? "#4caf50" : "#f44336" } }, msg) : null
282
+ )
196
283
  );
197
284
  }
198
285
  let lastJumpedTo = null;
package/dist/client.js CHANGED
@@ -42,7 +42,9 @@ __export(client_exports, {
42
42
  module.exports = __toCommonJS(client_exports);
43
43
  var React = __toESM(require("react"), 1);
44
44
  var name = "dsh-my-go";
45
- var inject = ["slots"];
45
+ var inject = ["slots", "settingsScope"];
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" };
46
48
  function apply(ctx) {
47
49
  const client = ctx;
48
50
  const slots = client.get("slots");
@@ -187,17 +189,102 @@ function apply(ctx) {
187
189
  style: { width: props && props.wide ? "100%" : 32, height: 32, border: "none", background: "transparent", cursor: "pointer" }
188
190
  }, "\u{1F9ED}")
189
191
  ));
192
+ const scope = client.get("settingsScope") ? client.get("settingsScope").bind({ namespace: "dsh-my-go" }) : null;
190
193
  slots.inject("settings.section", () => slots.register(
191
194
  { name: "settings.section", id: "dsh-my-go", order: 30, label: "MyGO \u7F16\u6392" },
192
- (props) => React.createElement(SettingsPage, props)
195
+ (props) => React.createElement(SettingsPage, { ...props, scope })
193
196
  ));
194
- function SettingsPage(_props) {
197
+ function SettingsPage({ scope: sp, close }) {
198
+ const [draft, setDraft] = React.useState(null);
199
+ const [saving, setSaving] = React.useState(false);
200
+ const [msg, setMsg] = React.useState(null);
201
+ React.useEffect(() => {
202
+ if (!sp) return;
203
+ try {
204
+ setDraft(sp.read());
205
+ } catch {
206
+ setDraft({});
207
+ }
208
+ }, [sp]);
209
+ if (!sp) return React.createElement("div", { style: { padding: 16, color: "#888" } }, "\u8BBE\u7F6E\u670D\u52A1\u4E0D\u53EF\u7528");
210
+ const set = (type, field, value) => {
211
+ setDraft((prev) => ({ ...prev, [type]: { ...prev?.[type], [field]: value } }));
212
+ };
213
+ const save = async () => {
214
+ setSaving(true);
215
+ setMsg(null);
216
+ try {
217
+ await sp.update(draft);
218
+ setMsg("\u5DF2\u4FDD\u5B58");
219
+ } catch (e) {
220
+ setMsg("\u4FDD\u5B58\u5931\u8D25: " + String(e));
221
+ } finally {
222
+ setSaving(false);
223
+ }
224
+ };
225
+ const inputStyle = { background: "var(--surface, #1e1e1e)", color: "var(--text, #e0e0e0)", border: "1px solid var(--separator, #333)", borderRadius: 4, padding: "4px 8px", fontSize: 13, width: "100%", boxSizing: "border-box" };
226
+ const labelStyle = { fontSize: 12, color: "var(--text-secondary, #888)", marginBottom: 2 };
227
+ const cardStyle = { border: "1px solid var(--separator, #333)", borderRadius: 8, padding: 12, marginBottom: 12 };
228
+ const rowStyle = { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8, marginBottom: 8 };
195
229
  return React.createElement(
196
230
  "div",
197
- { style: { padding: 16 } },
198
- React.createElement("h2", null, "MyGO \u7F16\u6392\u914D\u7F6E"),
199
- React.createElement("p", null, "\u6BCF\u4E2A\u5B50\u667A\u80FD\u4F53\u7684\u6A21\u578B / \u601D\u8003\u7A0B\u5EA6 / DSV4P0813 \u8865\u4E01\u5F00\u5173\u3002\u4FEE\u6539\u540E\u901A\u8FC7 Settings \u670D\u52A1\u6301\u4E45\u5316\u3002"),
200
- React.createElement("div", { style: { color: "#888", marginTop: 12 } }, "\u914D\u7F6E\u9879\u7531 host \u4FA7 settings \u547D\u540D\u7A7A\u95F4 dsh-my-go \u63D0\u4F9B\uFF1B\u4FEE\u6539\u540E\u751F\u6548\u4E8E\u4E0B\u4E00\u6B21\u6D3E\u53D1\u3002")
231
+ { style: { padding: 16, maxWidth: 600 } },
232
+ React.createElement("h2", { style: { margin: "0 0 4px" } }, "MyGO \u7F16\u6392\u914D\u7F6E"),
233
+ 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"),
234
+ ...AGENT_TYPES.map((type) => {
235
+ const cfg = draft?.[type] || {};
236
+ return React.createElement(
237
+ "div",
238
+ { key: type, style: cardStyle },
239
+ React.createElement("div", { style: { fontWeight: 600, marginBottom: 8 } }, AGENT_LABELS[type] || type),
240
+ React.createElement(
241
+ "div",
242
+ { style: rowStyle },
243
+ React.createElement(
244
+ "div",
245
+ null,
246
+ React.createElement("div", { style: labelStyle }, "Provider"),
247
+ React.createElement("input", { style: inputStyle, value: cfg.provider ?? "", placeholder: "\u7559\u7A7A\u8DDF\u968F Sisyphus", onChange: (e) => set(type, "provider", e.target.value) })
248
+ ),
249
+ React.createElement(
250
+ "div",
251
+ null,
252
+ React.createElement("div", { style: labelStyle }, "Model"),
253
+ React.createElement("input", { style: inputStyle, value: cfg.model ?? "", placeholder: "\u7559\u7A7A\u8DDF\u968F Sisyphus", onChange: (e) => set(type, "model", e.target.value) })
254
+ )
255
+ ),
256
+ React.createElement(
257
+ "div",
258
+ { style: rowStyle },
259
+ React.createElement(
260
+ "div",
261
+ null,
262
+ React.createElement("div", { style: labelStyle }, "Reasoning Effort"),
263
+ React.createElement("input", { style: inputStyle, value: cfg.reasoningEffort ?? "", placeholder: "low / high / max", onChange: (e) => set(type, "reasoningEffort", e.target.value) })
264
+ ),
265
+ React.createElement(
266
+ "div",
267
+ { style: { display: "flex", alignItems: "flex-end", gap: 8 } },
268
+ React.createElement(
269
+ "label",
270
+ { style: { display: "flex", alignItems: "center", gap: 6, cursor: "pointer", fontSize: 13, paddingTop: 18 } },
271
+ React.createElement("input", { type: "checkbox", checked: cfg.dsv4p0813 === true, onChange: (e) => set(type, "dsv4p0813", e.target.checked) }),
272
+ "DSV4P0813"
273
+ )
274
+ )
275
+ )
276
+ );
277
+ }),
278
+ React.createElement(
279
+ "div",
280
+ { style: { display: "flex", alignItems: "center", gap: 12, marginTop: 8 } },
281
+ React.createElement("button", {
282
+ onClick: save,
283
+ disabled: saving,
284
+ style: { padding: "6px 20px", borderRadius: 6, border: "none", background: "var(--brand, #0066ff)", color: "#fff", cursor: saving ? "wait" : "pointer", fontSize: 14 }
285
+ }, saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58"),
286
+ msg ? React.createElement("span", { style: { fontSize: 13, color: msg.startsWith("\u5DF2") ? "#4caf50" : "#f44336" } }, msg) : null
287
+ )
201
288
  );
202
289
  }
203
290
  let lastJumpedTo = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-my-go",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "DSH plugin: Sisyphus agent orchestration — star topology, single-line blocking, 7 specialist sub-agents (Hermes/Explore/Librarian/Looker/Hephaestus/Prometheus/Oracle) with per-type model binding, go_work/continue/need_help/forward communication tools, Web UI tree panel and settings.",
5
5
  "author": "daizihan233",
6
6
  "license": "MIT",
@@ -30,63 +30,12 @@
30
30
  config:
31
31
  maxBytes: 65536
32
32
 
33
- # Orchestration instructions: the model-facing contract for the four tools.
33
+ # Orchestration instructions: registered through the host `systemPrompt` registry
34
+ # by a dedicated consumer row (following the same pattern as `dsh-persona`).
35
+ # Mounting `@deepseek-ai/dsh-system-prompt` as a preset row would collide with
36
+ # the host-owned `systemPrompt` service provider at mount time.
34
37
  - id: orchestration-section
35
- name: '@deepseek-ai/dsh-system-prompt'
36
- config:
37
- section:
38
- name: dsh-my-go:orchestration
39
- order: 20
40
- text: |-
41
- # Sisyphus 编排规则
42
-
43
- 你是 Sisyphus:总调度 + 质检官。子智能体不直接通信,全部经由你中转。你根据每个步骤的
44
- 难度与类型挑选合适的工种,而不是把整个任务一次性甩给一个子智能体。
45
-
46
- ## 你的工具
47
- - `go_work(agent, prompt)` — 派发一个新子智能体(空上下文)。可用类型见下方「工种清单」。
48
- 单线阻塞:已有子智能体运行时,新任务进入队列,当前完成后自动开始。
49
- - `continue(id, prompt)` — 恢复一个子智能体(驳回/追问/传话)。被驳回的子智能体保留
50
- 当前轮次上下文继续执行,不需要重读已看过的内容。
51
- - `need_help` — 子智能体向你求助时使用(你会收到带 helpRequestId 的注入)。
52
- - `forward(from, target)` — 把一个 need_help 请求转发给目标(childId=继续,agent 类型=新派发)。
53
- - `orchestration_status` — 查看运行状态、队列、求助、历史结论。
54
- - `list_subagents` — 列出已派发的所有 sub-agent(类型/childId/状态/最后收到的 prompt)。
55
- 派发或复用前先调用它:能 continue 复用的(同任务、上下文有价值)就不要重新 go_work。
56
-
57
- ## 工种清单(你可调用的子智能体)
58
- - `prometheus` — 需求规划。调研、提问、细化需求,把模糊需求拆成**可执行步骤序列**
59
- (每步只描述做什么与交付物,不标工种)。仅在流程开始时调用一次;它输出计划后由你
60
- 接手调度——工种分配和调度是**你的**事,不是 prometheus 的。
61
- - `explore` — 快速检索。grep、读文件、定位符号、扫描目录结构。(触发词:查找/搜索/读取/定位)
62
- - `librarian` — 文档查询。读 README、API 参考、历史文档、注释提取。(触发词:文档/API/说明/参考)
63
- - `looker` — 多模态识别。UI 截图、设计稿、PDF 图表。(触发词:图片/截图/UI/设计稿)
64
- - `hermes` — 快速执行。批量替换、代码格式化、统一 imports、纯文本搬运。(触发词:替换/批量/格式化/统一)
65
- - `hephaestus` — 代码编写。单文件重构、模块实现、单元测试、常规代码生成。(触发词:写代码/实现/重构/修改)
66
- - `oracle` — 架构调试 + 终验。跨模块依赖分析、深层 Bug 定位、代码审查、最终验收。(触发词:调试/架构/审查/验证)
67
-
68
- ## 步骤级调度(重要)
69
- Prometheus 交来的计划是**步骤序列**,不是一份可以直接甩给 hephaestus 的大任务。你要
70
- **逐步骤决策**:
71
- 1. 看这一步的类型与难度(检索?实现?重构?验收?)。
72
- 2. 选择最省 token 的工种:轻活(检索/文档/批量)派轻工种(explore/librarian/hermes),
73
- 重活(写代码/调试/终验)派重工种(hephaestus/oracle)。
74
- 3. **沿用或换人**:下一步如果和上一步同一工种且上下文连续,`continue` 同一个 childId
75
- (它保留上下文,省 token);如果换了工种,才 `go_work` 新派。
76
- 4. 每步结论回来后先质检再决定下一步,不要一次把所有步骤都发出去。
77
-
78
- ## 质检规则
79
- 收到子智能体结论后,你有权驳回或追问:
80
- - 质量不达标 → `continue` 同一个 childId,附驳回理由和修正方向。
81
- - 需要另一工种 → 先驳回/结束当前,再 `go_work` 派发合适的类型。
82
- - 结论合格 → 向用户汇报,或按计划进入下一步。
83
-
84
- ## 禁止事项
85
- 1. 不要让子智能体直接调用其他子智能体(它们没有 go_work/continue/forward)。
86
- 2. 子智能体不得主动发起对话,只能被动响应你的分发。
87
- 3. 收到 intent=replan 时,必须切换智能体类型(如 hephaestus → oracle),而不是原地升级模型。
88
- 4. Prometheus 只做规划不执行;它的计划必须由你按步骤重新调度。
89
- 5. 不要用 `go_work` 重复派发一个已存在且可 continue 的子智能体——先用 `list_subagents` 查。
38
+ name: './tools/orchestration-section.mjs'
90
39
 
91
40
  # ── shell ───────────────────────────────────────────────────────────────────
92
41
  - id: tool-bash
@@ -127,6 +76,19 @@
127
76
  config:
128
77
  - id: plan-mode
129
78
  name: '@deepseek-ai/dsh-plan-mode'
79
+ config:
80
+ section: |
81
+ You are in plan mode. Stay in plan mode until exit_plan_mode succeeds or the user switches the session mode. Imperative language to implement changes means plan the implementation, not execute it. A user's conversational agreement — including an answer confirming something you asked — approves nothing and does not end plan mode; fold the confirmed decision into the plan and submit it through exit_plan_mode.
82
+
83
+ Explore first. Use non-mutating reads, searches, static analysis, and checks to ground the plan in the actual repository. Do not edit or write files, change configuration, run formatters or code generation that rewrites tracked files, commit, or otherwise carry out the plan. Prefer existing functions and patterns over new machinery.
84
+
85
+ The tool catalog stays the same across modes for request-cache stability. These plan-mode rules override any later tool description or guidance that suggests using mutation tools; those tools remain listed to keep the tool catalog unchanged. Do not use todo_write to track this planning phase: it tracks implementation after an approved plan, while the plan itself belongs in exit_plan_mode.
86
+
87
+ Resolve discoverable facts by inspection. Use ask_user_question only for user-owned choices or material ambiguity that inspection cannot answer. Do not ask the user where code lives or how current behavior works when you can find out.
88
+
89
+ Make the plan decision-complete: state the goal and success criteria; group implementation changes by subsystem; identify public API, schema, and data-flow changes; cover edge cases, failure modes, tests, acceptance criteria, and explicit assumptions. Keep it concise enough to review but detailed enough that another engineer can implement it without making design decisions.
90
+
91
+ When ready, call exit_plan_mode with the complete plan markdown, starting with a # title. Make exit_plan_mode the only and final tool call in that assistant response: it presents the plan for approval, and implementation begins only in a later step after approval. Do not paste the final plan as a plain reply or ask "should I proceed?" through prose or ask_user_question. If review rejects it, incorporate the feedback and present again. If the review channel is unavailable or aborted, stay in plan mode and ask the user to switch modes manually; do not proceed with implementation.
130
92
 
131
93
  - id: compaction
132
94
  name: cordis:group
@@ -191,9 +153,13 @@
191
153
  subagentProvider: spawn
192
154
  maxRounds: 64
193
155
 
194
- # The broker host plugin: orchestration tools + model binding.
195
- - id: broker
196
- name: './tools/broker.mjs'
156
+ # ── broker (orchestration tools + prompt section) ───────────────────────────
157
+ # Deliberately OUTSIDE the delegation group: this row only CONSUMES the host
158
+ # `tools` / `subagents` / `systemPrompt` registries (it publishes nothing), so
159
+ # it needs no isolate realm — and its `systemPrompt.section()` must land in the
160
+ # agent's scope, which an `isolate` realm would hide from the assembly.
161
+ - id: broker
162
+ name: './tools/broker.mjs'
197
163
 
198
164
  # ── remaining model-facing rows ─────────────────────────────────────────────
199
165
  - id: tool-ask-user
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Consumer row that registers the Sisyphus orchestration prompt section
3
+ * through the host `systemPrompt` registry.
4
+ *
5
+ * Pattern identical to `dsh-persona`: a top-level consumer that injects
6
+ * systemPrompt and calls section(). Unlike mounting `@deepseek-ai/dsh-system-prompt`
7
+ * (which PROVIDES the service and collides with the host-owned instance),
8
+ * this row only consumes the registry.
9
+ */
10
+
11
+ export const name = 'orchestration-section'
12
+
13
+ export const inject = ['systemPrompt']
14
+
15
+ const SECTION_TEXT = `# Sisyphus 编排规则
16
+
17
+ 你是 Sisyphus:总调度 + 质检官。子智能体不直接通信,全部经由你中转。你根据每个步骤的
18
+ 难度与类型挑选合适的工种,而不是把整个任务一次性甩给一个子智能体。
19
+
20
+ ## 你的工具
21
+ - \`go_work(agent, prompt)\` — 派发一个新子智能体(空上下文)。可用类型见下方「工种清单」。
22
+ 单线阻塞:已有子智能体运行时,新任务进入队列,当前完成后自动开始。
23
+ - \`continue(id, prompt)\` — 恢复一个子智能体(驳回/追问/传话)。被驳回的子智能体保留
24
+ 当前轮次上下文继续执行,不需要重读已看过的内容。
25
+ - \`need_help\` — 子智能体向你求助时使用(你会收到带 helpRequestId 的注入)。
26
+ - \`forward(from, target)\` — 把一个 need_help 请求转发给目标(childId=继续,agent 类型=新派发)。
27
+ - \`orchestration_status\` — 查看运行状态、队列、求助、历史结论。
28
+ - \`list_subagents\` — 列出已派发的所有 sub-agent(类型/childId/状态/最后收到的 prompt)。
29
+ 派发或复用前先调用它:能 continue 复用的(同任务、上下文有价值)就不要重新 go_work。
30
+
31
+ ## 工种清单(你可调用的子智能体)
32
+ - \`prometheus\` — 需求规划。调研、提问、细化需求,把模糊需求拆成**可执行步骤序列**
33
+ (每步只描述做什么与交付物,不标工种)。仅在流程开始时调用一次;它输出计划后由你
34
+ 接手调度——工种分配和调度是**你的**事,不是 prometheus 的。
35
+ - \`explore\` — 快速检索。grep、读文件、定位符号、扫描目录结构。(触发词:查找/搜索/读取/定位)
36
+ - \`librarian\` — 文档查询。读 README、API 参考、历史文档、注释提取。(触发词:文档/API/说明/参考)
37
+ - \`looker\` — 多模态识别。UI 截图、设计稿、PDF 图表。(触发词:图片/截图/UI/设计稿)
38
+ - \`hermes\` — 快速执行。批量替换、代码格式化、统一 imports、纯文本搬运。(触发词:替换/批量/格式化/统一)
39
+ - \`hephaestus\` — 代码编写。单文件重构、模块实现、单元测试、常规代码生成。(触发词:写代码/实现/重构/修改)
40
+ - \`oracle\` — 架构调试 + 终验。跨模块依赖分析、深层 Bug 定位、代码审查、最终验收。(触发词:调试/架构/审查/验证)
41
+
42
+ ## 步骤级调度(重要)
43
+ Prometheus 交来的计划是**步骤序列**,不是一份可以直接甩给 hephaestus 的大任务。你要
44
+ **逐步骤决策**:
45
+ 1. 看这一步的类型与难度(检索?实现?重构?验收?)。
46
+ 2. 选择最省 token 的工种:轻活(检索/文档/批量)派轻工种(explore/librarian/hermes),
47
+ 重活(写代码/调试/终验)派重工种(hephaestus/oracle)。
48
+ 3. **沿用或换人**:下一步如果和上一步同一工种且上下文连续,\`continue\` 同一个 childId
49
+ (它保留上下文,省 token);如果换了工种,才 \`go_work\` 新派。
50
+ 4. 每步结论回来后先质检再决定下一步,不要一次把所有步骤都发出去。
51
+
52
+ ## 质检规则
53
+ 收到子智能体结论后,你有权驳回或追问:
54
+ - 质量不达标 → \`continue\` 同一个 childId,附驳回理由和修正方向。
55
+ - 需要另一工种 → 先驳回/结束当前,再 \`go_work\` 派发合适的类型。
56
+ - 结论合格 → 向用户汇报,或按计划进入下一步。
57
+
58
+ ## 禁止事项
59
+ 1. 不要让子智能体直接调用其他子智能体(它们没有 go_work/continue/forward)。
60
+ 2. 子智能体不得主动发起对话,只能被动响应你的分发。
61
+ 3. 收到 intent=replan 时,必须切换智能体类型(如 hephaestus → oracle),而不是原地升级模型。
62
+ 4. Prometheus 只做规划不执行;它的计划必须由你按步骤重新调度。
63
+ 5. 不要用 \`go_work\` 重复派发一个已存在且可 continue 的子智能体——先用 \`list_subagents\` 查。`
64
+
65
+ export function apply(ctx) {
66
+ ctx.effect(() => ctx.systemPrompt.section({
67
+ name: 'dsh-my-go:orchestration',
68
+ order: 20,
69
+ text: SECTION_TEXT,
70
+ }), 'dsh-my-go-orchestration.section()')
71
+ }
package/src/client.js CHANGED
@@ -20,7 +20,10 @@ import * as React from 'react'
20
20
 
21
21
  export const name = 'dsh-my-go'
22
22
 
23
- export const inject = ['slots']
23
+ export const inject = ['slots', 'settingsScope']
24
+
25
+ const AGENT_TYPES = ['sisyphus', 'hermes', 'explore', 'librarian', 'looker', 'hephaestus', 'prometheus', 'oracle']
26
+ const AGENT_LABELS = { sisyphus: 'Sisyphus', hermes: 'Hermes', explore: 'Explore', librarian: 'Librarian', looker: 'Looker', hephaestus: 'Hephaestus', prometheus: 'Prometheus', oracle: 'Oracle' }
24
27
 
25
28
  export function apply(ctx) {
26
29
  const client = ctx
@@ -164,16 +167,85 @@ export function apply(ctx) {
164
167
  ))
165
168
 
166
169
  // ── settings page ───────────────────────────────────────────────────────
170
+ const scope = client.get('settingsScope')
171
+ ? client.get('settingsScope').bind({ namespace: 'dsh-my-go' })
172
+ : null
173
+
167
174
  slots.inject('settings.section', () => slots.register(
168
175
  { name: 'settings.section', id: 'dsh-my-go', order: 30, label: 'MyGO 编排' },
169
- (props) => React.createElement(SettingsPage, props),
176
+ (props) => React.createElement(SettingsPage, { ...props, scope }),
170
177
  ))
171
178
 
172
- function SettingsPage(_props) {
173
- return React.createElement('div', { style: { padding: 16 } },
174
- React.createElement('h2', null, 'MyGO 编排配置'),
175
- React.createElement('p', null, '每个子智能体的模型 / 思考程度 / DSV4P0813 补丁开关。修改后通过 Settings 服务持久化。'),
176
- React.createElement('div', { style: { color: '#888', marginTop: 12 } }, '配置项由 host 侧 settings 命名空间 dsh-my-go 提供;修改后生效于下一次派发。'),
179
+ function SettingsPage({ scope: sp, close }) {
180
+ const [draft, setDraft] = React.useState(null)
181
+ const [saving, setSaving] = React.useState(false)
182
+ const [msg, setMsg] = React.useState(null)
183
+
184
+ React.useEffect(() => {
185
+ if (!sp) return
186
+ try { setDraft(sp.read()) } catch { setDraft({}) }
187
+ }, [sp])
188
+
189
+ if (!sp) return React.createElement('div', { style: { padding: 16, color: '#888' } }, '设置服务不可用')
190
+
191
+ const set = (type, field, value) => {
192
+ setDraft((prev) => ({ ...prev, [type]: { ...prev?.[type], [field]: value } }))
193
+ }
194
+
195
+ const save = async () => {
196
+ setSaving(true); setMsg(null)
197
+ try {
198
+ await sp.update(draft)
199
+ setMsg('已保存')
200
+ } catch (e) {
201
+ setMsg('保存失败: ' + String(e))
202
+ } finally { setSaving(false) }
203
+ }
204
+
205
+ const inputStyle = { background: 'var(--surface, #1e1e1e)', color: 'var(--text, #e0e0e0)', border: '1px solid var(--separator, #333)', borderRadius: 4, padding: '4px 8px', fontSize: 13, width: '100%', boxSizing: 'border-box' }
206
+ const labelStyle = { fontSize: 12, color: 'var(--text-secondary, #888)', marginBottom: 2 }
207
+ const cardStyle = { border: '1px solid var(--separator, #333)', borderRadius: 8, padding: 12, marginBottom: 12 }
208
+ const rowStyle = { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginBottom: 8 }
209
+
210
+ return React.createElement('div', { style: { padding: 16, maxWidth: 600 } },
211
+ React.createElement('h2', { style: { margin: '0 0 4px' } }, 'MyGO 编排配置'),
212
+ React.createElement('p', { style: { margin: '0 0 16px', fontSize: 13, color: 'var(--text-secondary, #888)' } }, '每个子智能体的模型 / Provider / 思考程度 / DSV4P0813 补丁开关。修改后点保存,下次派发生效。'),
213
+ ...AGENT_TYPES.map((type) => {
214
+ const cfg = draft?.[type] || {}
215
+ return React.createElement('div', { key: type, style: cardStyle },
216
+ React.createElement('div', { style: { fontWeight: 600, marginBottom: 8 } }, AGENT_LABELS[type] || type),
217
+ React.createElement('div', { style: rowStyle },
218
+ React.createElement('div', null,
219
+ React.createElement('div', { style: labelStyle }, 'Provider'),
220
+ React.createElement('input', { style: inputStyle, value: cfg.provider ?? '', placeholder: '留空跟随 Sisyphus', onChange: (e) => set(type, 'provider', e.target.value) }),
221
+ ),
222
+ React.createElement('div', null,
223
+ React.createElement('div', { style: labelStyle }, 'Model'),
224
+ React.createElement('input', { style: inputStyle, value: cfg.model ?? '', placeholder: '留空跟随 Sisyphus', onChange: (e) => set(type, 'model', e.target.value) }),
225
+ ),
226
+ ),
227
+ React.createElement('div', { style: rowStyle },
228
+ React.createElement('div', null,
229
+ React.createElement('div', { style: labelStyle }, 'Reasoning Effort'),
230
+ React.createElement('input', { style: inputStyle, value: cfg.reasoningEffort ?? '', placeholder: 'low / high / max', onChange: (e) => set(type, 'reasoningEffort', e.target.value) }),
231
+ ),
232
+ React.createElement('div', { style: { display: 'flex', alignItems: 'flex-end', gap: 8 } },
233
+ React.createElement('label', { style: { display: 'flex', alignItems: 'center', gap: 6, cursor: 'pointer', fontSize: 13, paddingTop: 18 } },
234
+ React.createElement('input', { type: 'checkbox', checked: cfg.dsv4p0813 === true, onChange: (e) => set(type, 'dsv4p0813', e.target.checked) }),
235
+ 'DSV4P0813',
236
+ ),
237
+ ),
238
+ ),
239
+ )
240
+ }),
241
+ React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 12, marginTop: 8 } },
242
+ React.createElement('button', {
243
+ onClick: save,
244
+ disabled: saving,
245
+ style: { padding: '6px 20px', borderRadius: 6, border: 'none', background: 'var(--brand, #0066ff)', color: '#fff', cursor: saving ? 'wait' : 'pointer', fontSize: 14 },
246
+ }, saving ? '保存中…' : '保存'),
247
+ msg ? React.createElement('span', { style: { fontSize: 13, color: msg.startsWith('已') ? '#4caf50' : '#f44336' } }, msg) : null,
248
+ ),
177
249
  )
178
250
  }
179
251