dsh-plugin-subagent-director 0.2.1 → 0.3.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/CHANGELOG.md +60 -21
  2. package/LICENSE +21 -21
  3. package/README.md +80 -74
  4. package/cordis.patch.yml +11 -11
  5. package/lib/bridge-contract.d.ts +28 -0
  6. package/lib/bridge-contract.d.ts.map +1 -1
  7. package/lib/bridge-contract.js +6 -0
  8. package/lib/bridge-contract.js.map +1 -1
  9. package/lib/bridge-entry.d.ts +5 -1
  10. package/lib/bridge-entry.d.ts.map +1 -1
  11. package/lib/bridge-entry.js +6 -2
  12. package/lib/bridge-entry.js.map +1 -1
  13. package/lib/client/RoleCard.d.ts +3 -1
  14. package/lib/client/RoleCard.d.ts.map +1 -1
  15. package/lib/client/RoleCard.js +12 -3
  16. package/lib/client/RoleCard.js.map +1 -1
  17. package/lib/client/SubagentCloseAction.d.ts +32 -0
  18. package/lib/client/SubagentCloseAction.d.ts.map +1 -0
  19. package/lib/client/SubagentCloseAction.js +99 -0
  20. package/lib/client/SubagentCloseAction.js.map +1 -0
  21. package/lib/client/SubagentModelDock.d.ts +19 -9
  22. package/lib/client/SubagentModelDock.d.ts.map +1 -1
  23. package/lib/client/SubagentModelDock.js +79 -4
  24. package/lib/client/SubagentModelDock.js.map +1 -1
  25. package/lib/client/SubagentOptionsSection.js +10 -4
  26. package/lib/client/SubagentOptionsSection.js.map +1 -1
  27. package/lib/client/index.d.ts +5 -0
  28. package/lib/client/index.d.ts.map +1 -1
  29. package/lib/client/index.js +405 -18
  30. package/lib/client/index.js.map +1 -1
  31. package/lib/client/locales.d.ts +1 -1
  32. package/lib/client/locales.d.ts.map +1 -1
  33. package/lib/client/locales.js +24 -2
  34. package/lib/client/locales.js.map +1 -1
  35. package/lib/client/store-logic.d.ts +17 -0
  36. package/lib/client/store-logic.d.ts.map +1 -1
  37. package/lib/client/store-logic.js +27 -1
  38. package/lib/client/store-logic.js.map +1 -1
  39. package/lib/client/store.d.ts +2 -0
  40. package/lib/client/store.d.ts.map +1 -1
  41. package/lib/client/store.js +11 -2
  42. package/lib/client/store.js.map +1 -1
  43. package/lib/client/subagent-model.d.ts +13 -0
  44. package/lib/client/subagent-model.d.ts.map +1 -1
  45. package/lib/client/subagent-model.js +20 -0
  46. package/lib/client/subagent-model.js.map +1 -1
  47. package/lib/close-tool.d.ts +29 -0
  48. package/lib/close-tool.d.ts.map +1 -0
  49. package/lib/close-tool.js +60 -0
  50. package/lib/close-tool.js.map +1 -0
  51. package/lib/index.d.ts +1 -0
  52. package/lib/index.d.ts.map +1 -1
  53. package/lib/index.js +7 -0
  54. package/lib/index.js.map +1 -1
  55. package/lib/remote.d.ts +73 -3
  56. package/lib/remote.d.ts.map +1 -1
  57. package/lib/remote.js +169 -10
  58. package/lib/remote.js.map +1 -1
  59. package/lib/route-resolver.d.ts +7 -0
  60. package/lib/route-resolver.d.ts.map +1 -1
  61. package/lib/route-resolver.js +10 -1
  62. package/lib/route-resolver.js.map +1 -1
  63. package/lib/settings.d.ts.map +1 -1
  64. package/lib/settings.js +10 -2
  65. package/lib/settings.js.map +1 -1
  66. package/package.json +113 -113
@@ -77,12 +77,23 @@ window.__ModuleLoader__.load({
77
77
  "personaPlaceholder": "Optional behavior/identity text injected into the subagent…",
78
78
  "modelOptional": "Save the card to apply changes",
79
79
  "providerMissing": "No provider selected",
80
+ "toolFilter": "Tool set",
81
+ "toolFilterHint": "Restrict the subagent to these tools. Leave empty to inherit the parent's full tool set.",
82
+ "toolFilterNone": "Inherit parent tools (no restriction)",
83
+ "toolFilterEmpty": "No tools available",
80
84
  "restoreDone": "Defaults restored",
81
85
  "invalidRoleId": "Role id must be kebab-case (lowercase letters, digits, single hyphens).",
82
86
  "bridgeUnavailable": "The Subagent Director settings bridge is not available on this server. Please update/restart the web application so it installs the /subagent-director channel.",
83
87
  "modelRanOn": "Subagent ran on",
84
88
  "modelNotRecorded": "Subagent model not recorded yet",
85
- "modelRanOnTitle": "Model route: {model}"
89
+ "modelQueryFailed": "Subagent model unavailable",
90
+ "modelRanOnTitle": "Model route: {model}",
91
+ "closeContinuable": "Release subagent",
92
+ "closeContinuableTitle": "Release this continuable subagent (free its resident handle)",
93
+ "closingContinuable": "Releasing…",
94
+ "closedSubagent": "Released",
95
+ "confirmCloseContinuable": "Release continuable subagent “{id}”? It will stop being resident; you can no longer continue it with send_message.",
96
+ "closeFailed": "Release failed: {message}"
86
97
  };
87
98
  /** Chinese dictionary. */
88
99
  const zh = {
@@ -129,12 +140,23 @@ window.__ModuleLoader__.load({
129
140
  "personaPlaceholder": "注入子代理的可选行为/身份文案……",
130
141
  "modelOptional": "保存卡片以应用更改",
131
142
  "providerMissing": "未选择供应商",
143
+ "toolFilter": "工具集",
144
+ "toolFilterHint": "将子代理限制为这些工具。留空则继承父代理的完整工具集。",
145
+ "toolFilterNone": "继承父代理工具(不限制)",
146
+ "toolFilterEmpty": "无可用工具",
132
147
  "restoreDone": "已恢复默认",
133
148
  "invalidRoleId": "角色 id 必须为 kebab-case(小写字母、数字、单个连字符)。",
134
149
  "bridgeUnavailable": "此服务器尚未提供 Subagent Director 设置桥接通道(/subagent-director)。请重启 Web 应用以安装该通道后再试。",
135
150
  "modelRanOn": "子代理实际运行于",
136
151
  "modelNotRecorded": "尚未记录到子代理模型",
137
- "modelRanOnTitle": "模型路由:{model}"
152
+ "modelQueryFailed": "暂时无法获取子代理模型",
153
+ "modelRanOnTitle": "模型路由:{model}",
154
+ "closeContinuable": "终止可持续状态",
155
+ "closeContinuableTitle": "释放此可持续子代理(解除驻留句柄)",
156
+ "closingContinuable": "正在终止…",
157
+ "closedSubagent": "已终止",
158
+ "confirmCloseContinuable": "终止可持续子代理“{id}”?终止后将不再驻留,无法再用 send_message 继续它。",
159
+ "closeFailed": "终止失败:{message}"
138
160
  };
139
161
  //#endregion
140
162
  //#region src/bridge-contract.ts
@@ -144,6 +166,12 @@ window.__ModuleLoader__.load({
144
166
  const SUBAGENT_DIRECTOR_RPC_VIEW = "settingsView";
145
167
  /** Endpoint that applies one path-op mutation. */
146
168
  const SUBAGENT_DIRECTOR_RPC_MUTATE = "settingsMutate";
169
+ /** Endpoint that releases one resident continuable child of a live parent. */
170
+ const SUBAGENT_DIRECTOR_RPC_CLOSE = "subagentClose";
171
+ /** Endpoint that returns the actual provider/model of one child session. */
172
+ const SUBAGENT_DIRECTOR_RPC_MODEL = "subagentModel";
173
+ /** Endpoint that returns the model-visible tool catalog for role tool-set editing. */
174
+ const SUBAGENT_DIRECTOR_RPC_TOOLS = "toolCatalog";
147
175
  //#endregion
148
176
  //#region src/client/store-logic.ts
149
177
  /** Path of the roles map from the section root. */
@@ -177,7 +205,11 @@ window.__ModuleLoader__.load({
177
205
  ...optional(role.persona) !== void 0 ? { persona: optional(role.persona) } : {},
178
206
  ...optional(role.provider) !== void 0 ? { provider: optional(role.provider) } : {},
179
207
  ...optional(role.model) !== void 0 ? { model: optional(role.model) } : {},
180
- ...optional(role.reasoningEffort) !== void 0 ? { reasoningEffort: optional(role.reasoningEffort) } : {}
208
+ ...optional(role.reasoningEffort) !== void 0 ? { reasoningEffort: optional(role.reasoningEffort) } : {},
209
+ ...(role.toolFilter?.allow?.length ?? 0) > 0 ? { toolFilter: {
210
+ allow: role.toolFilter.allow,
211
+ deny: []
212
+ } } : {}
181
213
  }
182
214
  }];
183
215
  }
@@ -197,6 +229,31 @@ window.__ModuleLoader__.load({
197
229
  };
198
230
  }
199
231
  /**
232
+ * Diff the tool-set (allow list) between the stored role and the edited draft.
233
+ * The editor manages only `allow`; an existing `deny` is preserved on set and
234
+ * the whole filter is removed when the allow list is cleared. An empty allow
235
+ * list means "inherit the parent's full tool set" (issue #2 semantics).
236
+ * @param base - the role's field path (e.g. ['roles', id]).
237
+ */
238
+ function toolFilterOps(base, before, draft) {
239
+ const storedAllow = before?.toolFilter?.allow ?? [];
240
+ const nextAllow = draft.toolFilter?.allow ?? [];
241
+ const storedDeny = before?.toolFilter?.deny;
242
+ if (storedAllow.length === nextAllow.length && storedAllow.every((name, i) => name === nextAllow[i])) return void 0;
243
+ if (nextAllow.length === 0) return {
244
+ op: "unset",
245
+ path: [...base, "toolFilter"]
246
+ };
247
+ return {
248
+ op: "set",
249
+ path: [...base, "toolFilter"],
250
+ value: {
251
+ allow: [...nextAllow],
252
+ ...storedDeny !== void 0 ? { deny: storedDeny } : {}
253
+ }
254
+ };
255
+ }
256
+ /**
200
257
  * Diff one role between its stored value and the edited draft. Only changed
201
258
  * fields become ops; clearing a field becomes an unset that restores the
202
259
  * composition base / removes the user override.
@@ -214,6 +271,7 @@ window.__ModuleLoader__.load({
214
271
  push(fieldEdit([...base, "provider"], b.provider, draft.provider));
215
272
  push(fieldEdit([...base, "model"], b.model, draft.model));
216
273
  push(fieldEdit([...base, "reasoningEffort"], b.reasoningEffort, draft.reasoningEffort));
274
+ push(toolFilterOps(base, before, draft));
217
275
  return ops;
218
276
  }
219
277
  /**
@@ -291,6 +349,7 @@ window.__ModuleLoader__.load({
291
349
  revision: 0,
292
350
  providers: [],
293
351
  models: [],
352
+ tools: [],
294
353
  loading: false
295
354
  };
296
355
  }
@@ -354,10 +413,17 @@ window.__ModuleLoader__.load({
354
413
  s.loading = true;
355
414
  });
356
415
  try {
357
- const [providersResponse, modelsResponse, viewResult] = await Promise.all([
416
+ const [providersResponse, modelsResponse, viewResult, toolsResult] = await Promise.all([
358
417
  this.wire.llm.providers({}),
359
418
  this.wire.llm.models({}),
360
- this.callBridge(SUBAGENT_DIRECTOR_RPC_VIEW)
419
+ this.callBridge(SUBAGENT_DIRECTOR_RPC_VIEW),
420
+ this.callBridge(SUBAGENT_DIRECTOR_RPC_TOOLS).catch(() => ({
421
+ ok: false,
422
+ error: {
423
+ code: "internal",
424
+ message: "tool catalog unavailable"
425
+ }
426
+ }))
361
427
  ]);
362
428
  if (!providersResponse.result.ok) throw new Error(providersResponse.result.error.message);
363
429
  if (!modelsResponse.result.ok) throw new Error(modelsResponse.result.error.message);
@@ -368,12 +434,14 @@ window.__ModuleLoader__.load({
368
434
  const writable = viewResult.value.writable;
369
435
  const providers = providersResponse.result.value.providers;
370
436
  const models = modelsResponse.result.value.groups;
437
+ const tools = toolsResult.ok ? toolsResult.value.tools : [];
371
438
  this.store.update((s) => {
372
439
  s.status = "ready";
373
440
  s.error = null;
374
441
  s.writable = writable;
375
442
  s.providers = providers;
376
443
  s.models = models;
444
+ s.tools = tools;
377
445
  s.namespace = view;
378
446
  s.section = section;
379
447
  s.revision = view?.revision ?? 0;
@@ -611,7 +679,7 @@ window.__ModuleLoader__.load({
611
679
  if (!provider || !model) return [];
612
680
  return (groups.find((g) => g.id === provider)?.models.find((m) => m.id === model))?.reasoning?.efforts ?? [];
613
681
  }
614
- function RoleCard({ id, role, isDefault, groups, t, onSave, onDelete, onSetDefault }) {
682
+ function RoleCard({ id, role, isDefault, groups, tools, t, onSave, onDelete, onSetDefault }) {
615
683
  const [editing, setEditing] = (0, react.useState)(false);
616
684
  const [busy, setBusy] = (0, react.useState)(false);
617
685
  const [failure, setFailure] = (0, react.useState)(void 0);
@@ -621,7 +689,8 @@ window.__ModuleLoader__.load({
621
689
  persona: role.persona ?? "",
622
690
  provider: role.provider ?? "",
623
691
  model: role.model ?? "",
624
- reasoningEffort: role.reasoningEffort ?? ""
692
+ reasoningEffort: role.reasoningEffort ?? "",
693
+ toolFilter: { allow: role.toolFilter?.allow ?? [] }
625
694
  });
626
695
  const provider = draft.provider || role.provider;
627
696
  const model = draft.model || role.model;
@@ -658,6 +727,17 @@ window.__ModuleLoader__.load({
658
727
  [field]: value
659
728
  }));
660
729
  };
730
+ const toggleTool = (name) => {
731
+ setDraft((d) => {
732
+ const allow = d.toolFilter?.allow ?? [];
733
+ const next = allow.includes(name) ? allow.filter((n) => n !== name) : [...allow, name];
734
+ return {
735
+ ...d,
736
+ toolFilter: { allow: next }
737
+ };
738
+ });
739
+ };
740
+ const allowList = draft.toolFilter?.allow ?? [];
661
741
  if (editing) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
662
742
  style: cardStyle,
663
743
  children: [
@@ -783,6 +863,51 @@ window.__ModuleLoader__.load({
783
863
  })
784
864
  ]
785
865
  }),
866
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
867
+ style: rowStyle,
868
+ children: [
869
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
870
+ style: fieldLabelStyle,
871
+ children: t("toolFilter")
872
+ }),
873
+ tools.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
874
+ style: {
875
+ color: token.labelTertiary,
876
+ fontSize: 12
877
+ },
878
+ children: t("toolFilterEmpty")
879
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
880
+ style: {
881
+ display: "flex",
882
+ flexWrap: "wrap",
883
+ gap: "4px 14px"
884
+ },
885
+ children: tools.map((name) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
886
+ style: {
887
+ display: "inline-flex",
888
+ alignItems: "center",
889
+ gap: 4,
890
+ fontSize: 12,
891
+ color: token.labelSecondary,
892
+ cursor: "pointer"
893
+ },
894
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
895
+ type: "checkbox",
896
+ checked: allowList.includes(name),
897
+ onChange: () => toggleTool(name)
898
+ }), name]
899
+ }, name))
900
+ }),
901
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
902
+ style: {
903
+ color: token.labelTertiary,
904
+ fontSize: 11,
905
+ lineHeight: "15px"
906
+ },
907
+ children: allowList.length === 0 ? t("toolFilterNone") : t("toolFilterHint")
908
+ })
909
+ ]
910
+ }),
786
911
  failure !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
787
912
  style: {
788
913
  color: token.danger,
@@ -878,6 +1003,10 @@ window.__ModuleLoader__.load({
878
1003
  role.persona ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Metadata, {
879
1004
  label: t("persona"),
880
1005
  value: role.persona
1006
+ }) : null,
1007
+ role.toolFilter?.allow?.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Metadata, {
1008
+ label: t("toolFilter"),
1009
+ value: role.toolFilter.allow.join(", ")
881
1010
  }) : null
882
1011
  ]
883
1012
  }),
@@ -1006,6 +1135,7 @@ window.__ModuleLoader__.load({
1006
1135
  const roles = section?.roles ?? {};
1007
1136
  const entries = Object.entries(roles);
1008
1137
  const groups = state.models;
1138
+ const tools = state.tools;
1009
1139
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1010
1140
  style: sectionWidth,
1011
1141
  children: [
@@ -1032,6 +1162,7 @@ window.__ModuleLoader__.load({
1032
1162
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RolesBlock, {
1033
1163
  controller,
1034
1164
  groups,
1165
+ tools,
1035
1166
  writable,
1036
1167
  roles: entries,
1037
1168
  defaultRole: section?.defaultRole,
@@ -1237,7 +1368,7 @@ window.__ModuleLoader__.load({
1237
1368
  });
1238
1369
  }
1239
1370
  /** The role-template roster: cards plus an inline add form. */
1240
- function RolesBlock({ controller, groups, writable, roles, defaultRole, t }) {
1371
+ function RolesBlock({ controller, groups, tools, writable, roles, defaultRole, t }) {
1241
1372
  const [adding, setAdding] = (0, react.useState)(false);
1242
1373
  const [draft, setDraft] = (0, react.useState)({
1243
1374
  displayName: "",
@@ -1245,7 +1376,8 @@ window.__ModuleLoader__.load({
1245
1376
  persona: "",
1246
1377
  provider: "",
1247
1378
  model: "",
1248
- reasoningEffort: ""
1379
+ reasoningEffort: "",
1380
+ toolFilter: { allow: [] }
1249
1381
  });
1250
1382
  const [busy, setBusy] = (0, react.useState)(false);
1251
1383
  const [failure, setFailure] = (0, react.useState)(void 0);
@@ -1256,7 +1388,8 @@ window.__ModuleLoader__.load({
1256
1388
  persona: "",
1257
1389
  provider: "",
1258
1390
  model: "",
1259
- reasoningEffort: ""
1391
+ reasoningEffort: "",
1392
+ toolFilter: { allow: [] }
1260
1393
  });
1261
1394
  setFailure(void 0);
1262
1395
  setAdding(true);
@@ -1349,6 +1482,58 @@ window.__ModuleLoader__.load({
1349
1482
  }))
1350
1483
  })]
1351
1484
  }),
1485
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1486
+ style: rowStyle,
1487
+ children: [
1488
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
1489
+ style: fieldLabelStyle,
1490
+ children: t("toolFilter")
1491
+ }),
1492
+ tools.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1493
+ style: {
1494
+ color: token.labelTertiary,
1495
+ fontSize: 12
1496
+ },
1497
+ children: t("toolFilterEmpty")
1498
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1499
+ style: {
1500
+ display: "flex",
1501
+ flexWrap: "wrap",
1502
+ gap: "4px 14px"
1503
+ },
1504
+ children: tools.map((name) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1505
+ style: {
1506
+ display: "inline-flex",
1507
+ alignItems: "center",
1508
+ gap: 4,
1509
+ fontSize: 12,
1510
+ color: token.labelSecondary,
1511
+ cursor: "pointer"
1512
+ },
1513
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1514
+ type: "checkbox",
1515
+ checked: (draft.toolFilter?.allow ?? []).includes(name),
1516
+ onChange: () => setDraft((d) => {
1517
+ const allow = d.toolFilter?.allow ?? [];
1518
+ const next = allow.includes(name) ? allow.filter((n) => n !== name) : [...allow, name];
1519
+ return {
1520
+ ...d,
1521
+ toolFilter: { allow: next }
1522
+ };
1523
+ })
1524
+ }), name]
1525
+ }, name))
1526
+ }),
1527
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1528
+ style: {
1529
+ color: token.labelTertiary,
1530
+ fontSize: 11,
1531
+ lineHeight: "15px"
1532
+ },
1533
+ children: (draft.toolFilter?.allow?.length ?? 0) === 0 ? t("toolFilterNone") : t("toolFilterHint")
1534
+ })
1535
+ ]
1536
+ }),
1352
1537
  failure !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1353
1538
  style: {
1354
1539
  color: token.danger,
@@ -1387,6 +1572,7 @@ window.__ModuleLoader__.load({
1387
1572
  role,
1388
1573
  isDefault: defaultRole === id,
1389
1574
  groups,
1575
+ tools,
1390
1576
  t,
1391
1577
  onSave: (d) => controller.updateRole(id, role, d),
1392
1578
  onDelete: () => controller.removeRole(id),
@@ -1451,10 +1637,48 @@ window.__ModuleLoader__.load({
1451
1637
  function formatModelRef(ref) {
1452
1638
  return `${ref.provider}/${ref.model}`;
1453
1639
  }
1640
+ /**
1641
+ * Whether this session is a continuable child (the surface where the
1642
+ * "release sustained state" control is meaningful). Reads the catalog
1643
+ * address's mode; ordinary sessions and one-shot children are false.
1644
+ */
1645
+ function isContinuableChild(snapshot) {
1646
+ if (snapshot === null || snapshot === void 0) return false;
1647
+ const address = snapshot.subagent?.address;
1648
+ return address !== void 0 && address !== null && address.mode === "continuable";
1649
+ }
1650
+ /**
1651
+ * Merge a local snapshot-derived lookup with a remote (RPC) lookup: the local
1652
+ * provenance wins when present (the runtime's own record), otherwise the
1653
+ * remote result decides. Kept pure so the dock's data-source preference is
1654
+ * unit-testable without a wire.
1655
+ */
1656
+ function mergeModelLookup(local, remote) {
1657
+ return local.found ? local : remote;
1658
+ }
1454
1659
  //#endregion
1455
1660
  //#region src/client/SubagentModelDock.tsx
1661
+ /**
1662
+ * Subagent Director — M3b observability dock readout.
1663
+ *
1664
+ * Contributes a single ambient line to the `conversation.composer.dock` seat
1665
+ * (the band under the composer card). When the current session is an
1666
+ * addressed subagent child it shows the provider/model that child actually
1667
+ * ran on:
1668
+ * - fast path: the opened transcript's latest assistant message already
1669
+ * records provenance/requestConfig (zero extra RPC — see subagent-model.ts);
1670
+ * - fallback: current DSH runtimes do not populate those fields, so the
1671
+ * dock asks the Host bridge for the child's last `request/header` event
1672
+ * (`subagentModel` endpoint) and caches the answer per child session.
1673
+ * When neither source proves a model it degrades to a short notice. Ordinary
1674
+ * sessions render nothing, so the dock stays clean.
1675
+ *
1676
+ * The dock is an additive list slot declared by ui-conversation at runtime;
1677
+ * we only contribute an occupant, never re-declare it. Our compile-time
1678
+ * SlotMap augmentation in index.ts narrows the registration typing.
1679
+ */
1456
1680
  /** Inline styling using the shared token surface (no CSS pipeline; M2 deviation). */
1457
- const style = {
1681
+ const style$1 = {
1458
1682
  root: {
1459
1683
  display: "flex",
1460
1684
  alignItems: "center",
@@ -1470,26 +1694,179 @@ window.__ModuleLoader__.load({
1470
1694
  }
1471
1695
  };
1472
1696
  /** Render the provider/model readout for an addressed subagent, or nothing. */
1473
- function SubagentModelDock({ session, t }) {
1697
+ function SubagentModelDock({ session, rpc, t }) {
1698
+ const [query, setQuery] = (0, react.useState)({ status: "idle" });
1699
+ const cache = (0, react.useRef)(/* @__PURE__ */ new Map());
1700
+ const local = latestSubagentModel(session);
1701
+ const childSessionId = session?.subagent?.address?.childSessionId;
1702
+ const lastSeq = session && Array.isArray(session.nodes) && session.nodes.length > 0 ? session.nodes[session.nodes.length - 1].seq ?? 0 : 0;
1703
+ (0, react.useEffect)(() => {
1704
+ if (!isAddressedSubagent(session)) {
1705
+ setQuery({ status: "idle" });
1706
+ return;
1707
+ }
1708
+ if (local.found || childSessionId === void 0) return;
1709
+ const cached = cache.current.get(childSessionId);
1710
+ if (cached !== void 0) {
1711
+ setQuery(cached);
1712
+ return;
1713
+ }
1714
+ let alive = true;
1715
+ setQuery({ status: "querying" });
1716
+ rpc.call(SUBAGENT_DIRECTOR_RPC_CHANNEL, SUBAGENT_DIRECTOR_RPC_MODEL, { sessionId: childSessionId }).then((result) => {
1717
+ if (!alive) return;
1718
+ let next;
1719
+ if (result.ok) {
1720
+ const value = result.value;
1721
+ next = value.found === true ? {
1722
+ status: "found",
1723
+ ref: {
1724
+ found: true,
1725
+ provider: value.provider,
1726
+ model: value.model
1727
+ }
1728
+ } : { status: "missing" };
1729
+ } else next = { status: "failed" };
1730
+ cache.current.set(childSessionId, next);
1731
+ setQuery(next);
1732
+ }).catch(() => {
1733
+ if (!alive) return;
1734
+ const next = { status: "failed" };
1735
+ cache.current.set(childSessionId, next);
1736
+ setQuery(next);
1737
+ });
1738
+ return () => {
1739
+ alive = false;
1740
+ };
1741
+ }, [
1742
+ session?.sessionId,
1743
+ childSessionId,
1744
+ lastSeq,
1745
+ local.found,
1746
+ rpc
1747
+ ]);
1474
1748
  if (!isAddressedSubagent(session)) return null;
1475
- const lookup = latestSubagentModel(session);
1749
+ const lookup = mergeModelLookup(local, query.status === "found" ? query.ref : { found: false });
1476
1750
  if (!lookup.found) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1477
- style: style.root,
1751
+ style: style$1.root,
1478
1752
  role: "status",
1479
- children: t("modelNotRecorded")
1753
+ children: query.status === "failed" ? t("modelQueryFailed") : t("modelNotRecorded")
1480
1754
  });
1481
1755
  const ref = lookup;
1482
1756
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1483
- style: style.root,
1757
+ style: style$1.root,
1484
1758
  role: "status",
1485
1759
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("modelRanOn") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1486
- style: style.ref,
1760
+ style: style$1.ref,
1487
1761
  title: t("modelRanOnTitle", { model: formatModelRef(ref) }),
1488
1762
  children: formatModelRef(ref)
1489
1763
  })]
1490
1764
  });
1491
1765
  }
1492
1766
  //#endregion
1767
+ //#region src/client/SubagentCloseAction.tsx
1768
+ /**
1769
+ * Subagent Director — "release sustained state" header action (issue #1).
1770
+ *
1771
+ * Contributes one button to the `conversation.session.header.actions` seat
1772
+ * (the additive per-session control row beside the session title). It renders
1773
+ * only while the CURRENT session is a continuable subagent child
1774
+ * (snapshot.subagent.address.mode === 'continuable') and otherwise returns
1775
+ * null, so ordinary sessions and one-shot children see nothing.
1776
+ *
1777
+ * Clicking asks the Host bridge's `subagentClose` endpoint to
1778
+ * drainContinuableChildren under the address's durable parent authority; on
1779
+ * success the button turns into a settled label (the child's handle is
1780
+ * released), on failure a short inline error shows the core message.
1781
+ *
1782
+ * The seat is a list slot declared by ui-conversation; the framework session
1783
+ * standard kit supplies `useSession`/`sessionId` (dsh-client-runtime merge),
1784
+ * the registration injects the RPC caller.
1785
+ */
1786
+ /** Inline styling using the shared token surface (no CSS pipeline; M2 deviation). */
1787
+ const style = {
1788
+ wrap: {
1789
+ display: "inline-flex",
1790
+ alignItems: "center",
1791
+ gap: 8
1792
+ },
1793
+ button: {
1794
+ ...dangerButtonStyle,
1795
+ height: 24,
1796
+ fontSize: 12,
1797
+ padding: "0 10px"
1798
+ },
1799
+ settled: {
1800
+ color: token.labelTertiary,
1801
+ fontSize: 12,
1802
+ lineHeight: "16px"
1803
+ },
1804
+ error: {
1805
+ color: token.danger,
1806
+ fontSize: 12,
1807
+ lineHeight: "16px",
1808
+ maxWidth: 260,
1809
+ overflow: "hidden",
1810
+ textOverflow: "ellipsis",
1811
+ whiteSpace: "nowrap"
1812
+ }
1813
+ };
1814
+ /** Render the release-sustained-state button for a continuable child, or nothing. */
1815
+ function SubagentCloseAction({ useSession, sessionId, rpc, t }) {
1816
+ const session = useSession((s) => s);
1817
+ const [state, setState] = (0, react.useState)("idle");
1818
+ const [error, setError] = (0, react.useState)(null);
1819
+ (0, react.useEffect)(() => {
1820
+ setState("idle");
1821
+ setError(null);
1822
+ }, [sessionId]);
1823
+ if (!isContinuableChild(session)) return null;
1824
+ const address = session.subagent.address;
1825
+ const onClose = async () => {
1826
+ if (state === "closing") return;
1827
+ setState("closing");
1828
+ setError(null);
1829
+ try {
1830
+ const result = await rpc.call(SUBAGENT_DIRECTOR_RPC_CHANNEL, SUBAGENT_DIRECTOR_RPC_CLOSE, {
1831
+ parentSessionId: address.parentSessionId,
1832
+ childSessionId: address.childSessionId
1833
+ });
1834
+ if (result.ok) setState("closed");
1835
+ else {
1836
+ setState("failed");
1837
+ setError(result.error.message);
1838
+ }
1839
+ } catch {
1840
+ setState("failed");
1841
+ }
1842
+ };
1843
+ if (state === "closed") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1844
+ style: style.wrap,
1845
+ role: "status",
1846
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1847
+ style: style.settled,
1848
+ children: t("closedSubagent")
1849
+ })
1850
+ });
1851
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1852
+ style: style.wrap,
1853
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1854
+ type: "button",
1855
+ style: style.button,
1856
+ disabled: state === "closing",
1857
+ onClick: () => {
1858
+ if (typeof window === "undefined" || window.confirm(t("confirmCloseContinuable", { id: address.childSessionId }))) onClose();
1859
+ },
1860
+ title: t("closeContinuableTitle", { id: address.childSessionId }),
1861
+ children: state === "closing" ? t("closingContinuable") : t("closeContinuable")
1862
+ }), state === "failed" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1863
+ style: style.error,
1864
+ role: "alert",
1865
+ children: t("closeFailed", { message: error ?? "" })
1866
+ })]
1867
+ });
1868
+ }
1869
+ //#endregion
1493
1870
  //#region src/client/index.ts
1494
1871
  /** Dictionary namespace owned by Subagent Director (bilingual, typed). */
1495
1872
  const NS = "settings.subagentDirector";
@@ -1529,6 +1906,8 @@ window.__ModuleLoader__.load({
1529
1906
  api: connection.api,
1530
1907
  t
1531
1908
  });
1909
+ const dockInjected = () => ({ rpc: connection.rpc });
1910
+ const closeInjected = () => ({ rpc: connection.rpc });
1532
1911
  ctx.effect(() => {
1533
1912
  const refresh = () => refreshIfLoaded(controller);
1534
1913
  const disposers = [
@@ -1552,8 +1931,16 @@ window.__ModuleLoader__.load({
1552
1931
  name: "conversation.composer.dock",
1553
1932
  id: "subagent-director-model",
1554
1933
  order: 90,
1555
- locale: NS
1934
+ locale: NS,
1935
+ inject: dockInjected
1556
1936
  }, SubagentModelDock));
1937
+ ctx.slots.inject("conversation.session.header.actions", () => ctx.slots.register({
1938
+ name: "conversation.session.header.actions",
1939
+ id: "subagent-director-close",
1940
+ order: 20,
1941
+ locale: NS,
1942
+ inject: closeInjected
1943
+ }, SubagentCloseAction));
1557
1944
  }
1558
1945
  //#endregion
1559
1946
  exports.NS = NS;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@
5
5
  * ever reaches the runtime's bilingual balance check.
6
6
  */
7
7
  /** Keys for the settings.subagentDirector namespace (bilingual, enforced). */
8
- export type SubagentDirectorKey = 'nav' | 'sectionIntro' | 'defaultsHeading' | 'defaultsHint' | 'defaultProvider' | 'defaultModel' | 'defaultReasoningEffort' | 'restoreDefaults' | 'provider' | 'model' | 'reasoningEffort' | 'persona' | 'rolesHeading' | 'rolesHint' | 'addRole' | 'emptyRoles' | 'roleId' | 'roleDisplayName' | 'roleDescription' | 'rolePersona' | 'setDefaultRole' | 'defaultRoleBadge' | 'deleteRole' | 'confirmDeleteRole' | 'removeRoleDone' | 'addedRole' | 'roleUpdated' | 'conflict' | 'rejected' | 'fatal' | 'loadError' | 'readonly' | 'save' | 'cancel' | 'edit' | 'retry' | 'fallbackOnInvalid' | 'roleIdPlaceholder' | 'displayNamePlaceholder' | 'descriptionPlaceholder' | 'personaPlaceholder' | 'modelOptional' | 'providerMissing' | 'restoreDone' | 'invalidRoleId' | 'bridgeUnavailable' | 'modelRanOn' | 'modelNotRecorded' | 'modelRanOnTitle';
8
+ export type SubagentDirectorKey = 'nav' | 'sectionIntro' | 'defaultsHeading' | 'defaultsHint' | 'defaultProvider' | 'defaultModel' | 'defaultReasoningEffort' | 'restoreDefaults' | 'provider' | 'model' | 'reasoningEffort' | 'persona' | 'rolesHeading' | 'rolesHint' | 'addRole' | 'emptyRoles' | 'roleId' | 'roleDisplayName' | 'roleDescription' | 'rolePersona' | 'setDefaultRole' | 'defaultRoleBadge' | 'deleteRole' | 'confirmDeleteRole' | 'removeRoleDone' | 'addedRole' | 'roleUpdated' | 'conflict' | 'rejected' | 'fatal' | 'loadError' | 'readonly' | 'save' | 'cancel' | 'edit' | 'retry' | 'fallbackOnInvalid' | 'roleIdPlaceholder' | 'displayNamePlaceholder' | 'descriptionPlaceholder' | 'personaPlaceholder' | 'modelOptional' | 'providerMissing' | 'toolFilter' | 'toolFilterHint' | 'toolFilterNone' | 'toolFilterEmpty' | 'restoreDone' | 'invalidRoleId' | 'bridgeUnavailable' | 'modelRanOn' | 'modelNotRecorded' | 'modelQueryFailed' | 'modelRanOnTitle' | 'closeContinuable' | 'closeContinuableTitle' | 'closingContinuable' | 'closedSubagent' | 'confirmCloseContinuable' | 'closeFailed';
9
9
  /** English dictionary ($subagentDirector). */
10
10
  export declare const en: Record<SubagentDirectorKey, string>;
11
11
  /** Chinese dictionary. */
@@ -1 +1 @@
1
- {"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../src/client/locales.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,8EAA8E;AAC9E,MAAM,MAAM,mBAAmB,GAC3B,KAAK,GACL,cAAc,GACd,iBAAiB,GACjB,cAAc,GACd,iBAAiB,GACjB,cAAc,GACd,wBAAwB,GACxB,iBAAiB,GACjB,UAAU,GACV,OAAO,GACP,iBAAiB,GACjB,SAAS,GACT,cAAc,GACd,WAAW,GACX,SAAS,GACT,YAAY,GACZ,QAAQ,GACR,iBAAiB,GACjB,iBAAiB,GACjB,aAAa,GACb,gBAAgB,GAChB,kBAAkB,GAClB,YAAY,GACZ,mBAAmB,GACnB,gBAAgB,GAChB,WAAW,GACX,aAAa,GACb,UAAU,GACV,UAAU,GACV,OAAO,GACP,WAAW,GACX,UAAU,GACV,MAAM,GACN,QAAQ,GACR,MAAM,GACN,OAAO,GACP,mBAAmB,GACnB,mBAAmB,GACnB,wBAAwB,GACxB,wBAAwB,GACxB,oBAAoB,GACpB,eAAe,GACf,iBAAiB,GACjB,aAAa,GACb,eAAe,GACf,mBAAmB,GACnB,YAAY,GACZ,kBAAkB,GAClB,iBAAiB,CAAC;AAEtB,8CAA8C;AAC9C,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAkDlD,CAAC;AAEF,0BAA0B;AAC1B,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAkDlD,CAAC"}
1
+ {"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../src/client/locales.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,8EAA8E;AAC9E,MAAM,MAAM,mBAAmB,GAC3B,KAAK,GACL,cAAc,GACd,iBAAiB,GACjB,cAAc,GACd,iBAAiB,GACjB,cAAc,GACd,wBAAwB,GACxB,iBAAiB,GACjB,UAAU,GACV,OAAO,GACP,iBAAiB,GACjB,SAAS,GACT,cAAc,GACd,WAAW,GACX,SAAS,GACT,YAAY,GACZ,QAAQ,GACR,iBAAiB,GACjB,iBAAiB,GACjB,aAAa,GACb,gBAAgB,GAChB,kBAAkB,GAClB,YAAY,GACZ,mBAAmB,GACnB,gBAAgB,GAChB,WAAW,GACX,aAAa,GACb,UAAU,GACV,UAAU,GACV,OAAO,GACP,WAAW,GACX,UAAU,GACV,MAAM,GACN,QAAQ,GACR,MAAM,GACN,OAAO,GACP,mBAAmB,GACnB,mBAAmB,GACnB,wBAAwB,GACxB,wBAAwB,GACxB,oBAAoB,GACpB,eAAe,GACf,iBAAiB,GACjB,YAAY,GACZ,gBAAgB,GAChB,gBAAgB,GAChB,iBAAiB,GACjB,aAAa,GACb,eAAe,GACf,mBAAmB,GACnB,YAAY,GACZ,kBAAkB,GAClB,kBAAkB,GAClB,iBAAiB,GACjB,kBAAkB,GAClB,uBAAuB,GACvB,oBAAoB,GACpB,gBAAgB,GAChB,yBAAyB,GACzB,aAAa,CAAC;AAElB,8CAA8C;AAC9C,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,mBAAmB,EAAE,MAAM,CA6DlD,CAAC;AAEF,0BAA0B;AAC1B,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,mBAAmB,EAAE,MAAM,CA6DlD,CAAC"}