@deepseek-ai/dsh-client-ui-subagent 0.1.6-alpha.1 → 0.1.7-alpha.1
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.i18n.yaml +2 -2
- package/README.md +14 -6
- package/README.zh.md +14 -6
- package/lib/client.js +370 -266
- package/lib/types/client/SubagentHeaderLineage.d.ts +15 -4
- package/lib/types/client/SubagentReadOnlyComposer.d.ts +1 -1
- package/lib/types/client/index.d.ts +2 -2
- package/lib/types/client/locales.d.ts +5 -4
- package/lib/types/client/sidebar-chat/index.d.ts +62 -0
- package/package.json +25 -17
- package/lib/types/client/subagent-lineage.d.ts +0 -21
package/lib/client.js
CHANGED
|
@@ -9,13 +9,13 @@ window.__ModuleLoader__.load({
|
|
|
9
9
|
let react_dom = require("react-dom");
|
|
10
10
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
11
11
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-subagent/src/client/SubagentHeaderLineage.module.css.mjs
|
|
12
|
-
const css$
|
|
13
|
-
const tagId$
|
|
14
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$
|
|
12
|
+
const css$2 = ".ZKlsPq_root{align-items:center;gap:10px;min-width:0;display:inline-flex;position:relative}.ZKlsPq_switcherRoot{min-width:0;margin-left:6px}.ZKlsPq_trigger,.ZKlsPq_switcherTrigger{min-height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:6px;align-items:center;padding:3px 2px;font-size:12px;line-height:18px;display:inline-flex}.ZKlsPq_trigger{gap:4px}.ZKlsPq_switcherTrigger{min-width:0;max-width:244px;color:var(--dsw-alias-label-primary);gap:4px;font-weight:500}.ZKlsPq_ancestorSwitcherTrigger{color:var(--dsw-alias-label-tertiary);font-weight:400}.ZKlsPq_switcherTitle{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.ZKlsPq_switcherTrigger svg{flex:none}.ZKlsPq_activitySlot{flex:none;justify-content:center;align-items:center;width:14px;height:14px;display:inline-flex}.ZKlsPq_trigger:hover,.ZKlsPq_trigger:focus-visible{color:var(--dsw-alias-label-secondary)}.ZKlsPq_switcherTrigger:hover,.ZKlsPq_switcherTrigger:focus-visible{color:var(--dsw-alias-label-primary)}.ZKlsPq_ancestorSwitcherTrigger:hover,.ZKlsPq_ancestorSwitcherTrigger:focus-visible{color:var(--dsw-alias-label-tertiary)}.ZKlsPq_trigger svg,.ZKlsPq_switcherTrigger svg{transition:transform .12s}.ZKlsPq_triggerOpen{transform:rotate(180deg)}.ZKlsPq_menu{z-index:100;box-sizing:border-box;background:var(--dsw-specific-menu);width:336px;max-width:min(400px,100vw - 32px);max-height:min(560px,100vh - 140px);backdrop-filter:var(--dsw-menu-backdrop-filter);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);box-shadow:var(--dsw-elevation-prominent);border-radius:16px;flex-direction:column;padding:3px;display:flex;position:fixed;overflow:auto}.ZKlsPq_node{min-width:0;position:relative}.ZKlsPq_menu>.ZKlsPq_node{margin-left:-2px}.ZKlsPq_row{box-sizing:border-box;width:100%;min-height:44px;color:var(--dsw-alias-label-primary);text-align:left;cursor:pointer;background:0 0;border:0;border-radius:7px;outline:none;align-items:flex-start;gap:6px;padding:6px 7px 6px 9px;font-size:12px;line-height:17px;display:flex;position:relative}.ZKlsPq_row:hover>.ZKlsPq_clickarea,.ZKlsPq_row:focus-visible>.ZKlsPq_clickarea{background:var(--dsw-alias-interactive-bg-hover)}.ZKlsPq_clickarea{box-sizing:border-box;border-radius:7px;flex:1;align-self:stretch;align-items:flex-start;gap:6px;min-width:0;margin:-6px -7px;padding:6px 7px;display:flex}.ZKlsPq_rowActivitySlot{flex:none;justify-content:center;align-items:center;width:14px;height:17px;display:inline-flex}.ZKlsPq_disclosure,.ZKlsPq_disclosureSpace{flex:none;width:14px;height:17px}.ZKlsPq_disclosure{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;justify-content:center;align-items:center;padding:0;transition:transform .12s;display:inline-flex}.ZKlsPq_disclosure svg{width:12px;height:12px}.ZKlsPq_disclosure:hover{color:var(--dsw-alias-label-primary)}.ZKlsPq_disclosureOpen{transform:rotate(90deg)}.ZKlsPq_content{flex-direction:column;flex:1;min-width:0;display:flex}.ZKlsPq_label,.ZKlsPq_summary{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.ZKlsPq_label{color:inherit;font-weight:400}.ZKlsPq_currentLabel{font-weight:600}.ZKlsPq_summary,.ZKlsPq_metrics{color:var(--dsw-alias-label-tertiary);font-size:10px;line-height:15px}.ZKlsPq_metrics{font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap;flex:none;grid-template-rows:17px 15px;display:grid}.ZKlsPq_metricToken{grid-row:1;line-height:17px}.ZKlsPq_metricDuration{grid-row:2}.ZKlsPq_sidebarButton{corner-shape:round;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:50%;flex:none;justify-content:center;align-items:center;margin:4px 0;padding:6px;display:inline-flex}.ZKlsPq_sidebarButton:hover,.ZKlsPq_sidebarButton:focus-visible{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.ZKlsPq_children{margin-left:16px;padding-left:3px;position:relative}.ZKlsPq_children:before,.ZKlsPq_children>.ZKlsPq_node:before{content:\"\";border-left:.5px solid var(--dsw-alias-border-l2);position:absolute;left:0}.ZKlsPq_children:before{height:23px;top:-23px}.ZKlsPq_children[aria-busy=true]:before{content:none}.ZKlsPq_children>.ZKlsPq_node:before{top:0;bottom:0;left:-3px}.ZKlsPq_children>.ZKlsPq_node:last-child:before{height:15px;bottom:auto}.ZKlsPq_children>.ZKlsPq_node>.ZKlsPq_row:before{content:\"\";border-top:.5px solid var(--dsw-alias-border-l2);width:12px;position:absolute;top:14px;left:-3px}.ZKlsPq_notice,.ZKlsPq_error{color:var(--dsw-alias-label-tertiary);padding:8px 10px;font-size:11px;line-height:16px}.ZKlsPq_error{color:var(--dsw-alias-state-error-primary);justify-content:space-between;align-items:center;gap:10px;display:flex}.ZKlsPq_refresh{color:inherit;cursor:pointer;background:0 0;border:0;border-radius:5px;flex:none;align-items:center;gap:3px;padding:3px 5px;display:inline-flex}.ZKlsPq_refresh svg{width:12px;height:12px}.ZKlsPq_refresh:hover{background:var(--dsw-alias-interactive-bg-hover)}";
|
|
13
|
+
const tagId$2 = "@deepseek-ai/dsh-client-ui-subagent/SubagentHeaderLineage.module.css";
|
|
14
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
|
|
15
15
|
const tag = document.createElement("style");
|
|
16
16
|
tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-subagent";
|
|
17
|
-
tag.dataset.pluginCss = tagId$
|
|
18
|
-
tag.textContent = css$
|
|
17
|
+
tag.dataset.pluginCss = tagId$2;
|
|
18
|
+
tag.textContent = css$2;
|
|
19
19
|
document.head.appendChild(tag);
|
|
20
20
|
}
|
|
21
21
|
var SubagentHeaderLineage_module_css_default = {
|
|
@@ -25,13 +25,11 @@ window.__ModuleLoader__.load({
|
|
|
25
25
|
"clickarea": "ZKlsPq_clickarea",
|
|
26
26
|
"content": "ZKlsPq_content",
|
|
27
27
|
"currentLabel": "ZKlsPq_currentLabel",
|
|
28
|
-
"disabled": "ZKlsPq_disabled",
|
|
29
28
|
"disclosure": "ZKlsPq_disclosure",
|
|
30
29
|
"disclosureOpen": "ZKlsPq_disclosureOpen",
|
|
31
30
|
"disclosureSpace": "ZKlsPq_disclosureSpace",
|
|
32
31
|
"error": "ZKlsPq_error",
|
|
33
32
|
"label": "ZKlsPq_label",
|
|
34
|
-
"loadingRow": "ZKlsPq_loadingRow",
|
|
35
33
|
"menu": "ZKlsPq_menu",
|
|
36
34
|
"metricDuration": "ZKlsPq_metricDuration",
|
|
37
35
|
"metricToken": "ZKlsPq_metricToken",
|
|
@@ -41,7 +39,8 @@ window.__ModuleLoader__.load({
|
|
|
41
39
|
"refresh": "ZKlsPq_refresh",
|
|
42
40
|
"root": "ZKlsPq_root",
|
|
43
41
|
"row": "ZKlsPq_row",
|
|
44
|
-
"
|
|
42
|
+
"rowActivitySlot": "ZKlsPq_rowActivitySlot",
|
|
43
|
+
"sidebarButton": "ZKlsPq_sidebarButton",
|
|
45
44
|
"summary": "ZKlsPq_summary",
|
|
46
45
|
"switcherRoot": "ZKlsPq_switcherRoot",
|
|
47
46
|
"switcherTitle": "ZKlsPq_switcherTitle",
|
|
@@ -50,44 +49,7 @@ window.__ModuleLoader__.load({
|
|
|
50
49
|
"triggerOpen": "ZKlsPq_triggerOpen"
|
|
51
50
|
};
|
|
52
51
|
//#endregion
|
|
53
|
-
//#region lib/types/client/subagent-lineage.js
|
|
54
|
-
/** UI Subagent-owned projection of descendant counts from Session summaries. */
|
|
55
|
-
/**
|
|
56
|
-
* Index uninterrupted subagent descendants under each ancestor.
|
|
57
|
-
* @param summaries - Session summaries keyed by id.
|
|
58
|
-
* @returns descendant totals keyed by possible parent id.
|
|
59
|
-
*/
|
|
60
|
-
function indexSubagentDescendants(summaries) {
|
|
61
|
-
const indexed = /* @__PURE__ */ new Map();
|
|
62
|
-
for (const descendant of Object.values(summaries)) {
|
|
63
|
-
if (descendant.origin !== "subagent") continue;
|
|
64
|
-
const seen = /* @__PURE__ */ new Set();
|
|
65
|
-
let current = descendant;
|
|
66
|
-
while (current?.origin === "subagent" && current.parentId !== void 0 && !seen.has(current.id)) {
|
|
67
|
-
seen.add(current.id);
|
|
68
|
-
const aggregate = indexed.get(current.parentId);
|
|
69
|
-
if (aggregate === void 0) indexed.set(current.parentId, {
|
|
70
|
-
count: 1,
|
|
71
|
-
runningCount: descendant.running ? 1 : 0
|
|
72
|
-
});
|
|
73
|
-
else {
|
|
74
|
-
aggregate.count += 1;
|
|
75
|
-
if (descendant.running) aggregate.runningCount += 1;
|
|
76
|
-
}
|
|
77
|
-
current = summaries[current.parentId];
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
return indexed;
|
|
81
|
-
}
|
|
82
|
-
//#endregion
|
|
83
52
|
//#region lib/types/client/SubagentHeaderLineage.js
|
|
84
|
-
function diagnosticReason(entry, t) {
|
|
85
|
-
switch (entry.reason) {
|
|
86
|
-
case "corrupt": return t("diagnostic.corrupt");
|
|
87
|
-
case "unsupported": return t("diagnostic.unsupported");
|
|
88
|
-
case "unavailable": return t("diagnostic.unavailable");
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
53
|
function treeItems(root) {
|
|
92
54
|
return root === null ? [] : Array.from(root.querySelectorAll("[role=\"treeitem\"]:not([aria-disabled=\"true\"])"));
|
|
93
55
|
}
|
|
@@ -168,10 +130,6 @@ window.__ModuleLoader__.load({
|
|
|
168
130
|
seconds: String(seconds).padStart(2, "0")
|
|
169
131
|
});
|
|
170
132
|
}
|
|
171
|
-
const NO_DESCENDANTS = {
|
|
172
|
-
count: 0,
|
|
173
|
-
runningCount: 0
|
|
174
|
-
};
|
|
175
133
|
function SubagentSwitcherIcon() {
|
|
176
134
|
return (0, react_jsx_runtime.jsxs)("svg", {
|
|
177
135
|
width: "16",
|
|
@@ -190,95 +148,56 @@ window.__ModuleLoader__.load({
|
|
|
190
148
|
})]
|
|
191
149
|
});
|
|
192
150
|
}
|
|
193
|
-
/** Render
|
|
194
|
-
function CatalogLoadingRows({
|
|
195
|
-
|
|
196
|
-
if (children.length === 0) return (0, react_jsx_runtime.jsx)("div", {
|
|
151
|
+
/** Render catalog loading without inventing child membership. */
|
|
152
|
+
function CatalogLoadingRows({ t }) {
|
|
153
|
+
return (0, react_jsx_runtime.jsx)("div", {
|
|
197
154
|
className: SubagentHeaderLineage_module_css_default.notice,
|
|
198
155
|
children: t("loading.label")
|
|
199
156
|
});
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
"aria-disabled": "true",
|
|
205
|
-
"aria-level": level,
|
|
206
|
-
"aria-label": t("loading.aria"),
|
|
207
|
-
className: `${SubagentHeaderLineage_module_css_default.row} ${SubagentHeaderLineage_module_css_default.disabled} ${SubagentHeaderLineage_module_css_default.loadingRow}`,
|
|
208
|
-
children: [
|
|
209
|
-
(0, react_jsx_runtime.jsx)("span", { className: SubagentHeaderLineage_module_css_default.disclosureSpace }),
|
|
210
|
-
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: summary.running ? "ongoing" : "done" }),
|
|
211
|
-
(0, react_jsx_runtime.jsx)("span", {
|
|
212
|
-
className: SubagentHeaderLineage_module_css_default.content,
|
|
213
|
-
children: (0, react_jsx_runtime.jsx)("span", {
|
|
214
|
-
className: SubagentHeaderLineage_module_css_default.label,
|
|
215
|
-
children: t("loading.label")
|
|
216
|
-
})
|
|
217
|
-
})
|
|
218
|
-
]
|
|
219
|
-
})
|
|
220
|
-
}, summary.id));
|
|
157
|
+
}
|
|
158
|
+
/** A child becomes a known leaf only after its own authoritative catalog loads empty. */
|
|
159
|
+
function isKnownLeaf(catalog) {
|
|
160
|
+
return catalog?.state === "ready" && catalog.entries.length === 0;
|
|
221
161
|
}
|
|
222
162
|
/** Render one catalog level and recurse only through explicitly expanded rows. */
|
|
223
|
-
function CatalogRows({ parentSessionId, currentSessionId, catalog, catalogs, summaries, expanded, level,
|
|
163
|
+
function CatalogRows({ parentSessionId, currentSessionId, catalog, catalogs, summaries, expanded, level, openChild, openChildAside, refreshProjection, toggleBranch, closeCatalog, t }) {
|
|
164
|
+
const [now, setNow] = (0, react.useState)(() => Date.now());
|
|
165
|
+
const running = catalog.entries.some((entry) => entry.activity === "running");
|
|
166
|
+
(0, react.useEffect)(() => {
|
|
167
|
+
if (!running) return;
|
|
168
|
+
const timer = setInterval(() => {
|
|
169
|
+
setNow(Date.now());
|
|
170
|
+
}, 1e3);
|
|
171
|
+
return () => {
|
|
172
|
+
clearInterval(timer);
|
|
173
|
+
};
|
|
174
|
+
}, [running]);
|
|
224
175
|
const emptyLoading = catalog.state === "loading" && catalog.entries.length === 0;
|
|
225
|
-
const reserveDisclosure = catalog.entries.some((entry) => entry.
|
|
176
|
+
const reserveDisclosure = catalog.entries.some((entry) => !isKnownLeaf(catalogs[entry.id]));
|
|
226
177
|
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
227
|
-
emptyLoading && (0, react_jsx_runtime.jsx)(CatalogLoadingRows, {
|
|
228
|
-
parentSessionId,
|
|
229
|
-
summaries,
|
|
230
|
-
level,
|
|
231
|
-
t
|
|
232
|
-
}),
|
|
178
|
+
emptyLoading && (0, react_jsx_runtime.jsx)(CatalogLoadingRows, { t }),
|
|
233
179
|
catalog.state === "error" && (0, react_jsx_runtime.jsxs)("div", {
|
|
234
180
|
className: SubagentHeaderLineage_module_css_default.error,
|
|
235
181
|
children: [(0, react_jsx_runtime.jsx)("span", { children: catalog.error?.message ?? t("load.error") }), (0, react_jsx_runtime.jsxs)("button", {
|
|
236
182
|
type: "button",
|
|
237
183
|
className: SubagentHeaderLineage_module_css_default.refresh,
|
|
238
184
|
onClick: () => {
|
|
239
|
-
|
|
185
|
+
refreshProjection(parentSessionId);
|
|
240
186
|
},
|
|
241
|
-
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.
|
|
187
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutlineRegular, { size: 14 }), t("retry")]
|
|
242
188
|
})]
|
|
243
189
|
}),
|
|
244
190
|
catalog.entries.map((entry) => {
|
|
245
|
-
if (entry.kind === "diagnostic") {
|
|
246
|
-
const reason = diagnosticReason(entry, t);
|
|
247
|
-
return (0, react_jsx_runtime.jsx)("div", {
|
|
248
|
-
className: SubagentHeaderLineage_module_css_default.node,
|
|
249
|
-
children: (0, react_jsx_runtime.jsxs)("div", {
|
|
250
|
-
role: "treeitem",
|
|
251
|
-
"aria-disabled": "true",
|
|
252
|
-
"aria-level": level,
|
|
253
|
-
"aria-label": `${entry.id} ${reason}`,
|
|
254
|
-
className: `${SubagentHeaderLineage_module_css_default.row} ${SubagentHeaderLineage_module_css_default.disabled}`,
|
|
255
|
-
title: reason,
|
|
256
|
-
children: [
|
|
257
|
-
reserveDisclosure && (0, react_jsx_runtime.jsx)("span", { className: SubagentHeaderLineage_module_css_default.disclosureSpace }),
|
|
258
|
-
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "error" }),
|
|
259
|
-
(0, react_jsx_runtime.jsxs)("span", {
|
|
260
|
-
className: SubagentHeaderLineage_module_css_default.content,
|
|
261
|
-
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
262
|
-
className: SubagentHeaderLineage_module_css_default.label,
|
|
263
|
-
children: entry.id
|
|
264
|
-
}), (0, react_jsx_runtime.jsx)("span", {
|
|
265
|
-
className: SubagentHeaderLineage_module_css_default.summary,
|
|
266
|
-
children: reason
|
|
267
|
-
})]
|
|
268
|
-
})
|
|
269
|
-
]
|
|
270
|
-
})
|
|
271
|
-
}, entry.id);
|
|
272
|
-
}
|
|
273
191
|
const childCatalog = catalogs[entry.id];
|
|
274
192
|
const isCurrent = entry.id === currentSessionId;
|
|
275
193
|
const isExpanded = expanded.has(entry.id);
|
|
276
|
-
const knownLeaf =
|
|
194
|
+
const knownLeaf = isKnownLeaf(childCatalog);
|
|
277
195
|
const childLoading = childCatalog === void 0 || childCatalog.state === "loading" && childCatalog.entries.length === 0;
|
|
278
196
|
const summary = summaries[entry.id];
|
|
279
197
|
const label = entry.label ?? entry.id;
|
|
280
|
-
const mode = entry.mode === "one-shot" ? t("mode.oneShot") : t("mode.continuable");
|
|
281
|
-
const
|
|
198
|
+
const mode = entry.mode === "unknown" ? t("mode.unknown") : entry.mode === "one-shot" ? t("mode.oneShot") : t("mode.continuable");
|
|
199
|
+
const completed = entry.activity === "inactive" && summary?.projectionValues?.subagentTiming?.lastTurnCompleted === true;
|
|
200
|
+
const activity = entry.activity === "running" ? t("activity.running") : completed ? t("activity.completed") : t("activity.inactive");
|
|
282
201
|
const secondary = [
|
|
283
202
|
summary?.title,
|
|
284
203
|
mode,
|
|
@@ -300,6 +219,16 @@ window.__ModuleLoader__.load({
|
|
|
300
219
|
});
|
|
301
220
|
closeCatalog();
|
|
302
221
|
};
|
|
222
|
+
const openAside = (event) => {
|
|
223
|
+
event.preventDefault();
|
|
224
|
+
event.stopPropagation();
|
|
225
|
+
openChildAside({
|
|
226
|
+
parentSessionId,
|
|
227
|
+
childSessionId: entry.id,
|
|
228
|
+
mode: entry.mode
|
|
229
|
+
});
|
|
230
|
+
closeCatalog();
|
|
231
|
+
};
|
|
303
232
|
const handleKey = (event) => {
|
|
304
233
|
if (event.key === "Enter" || event.key === " ") {
|
|
305
234
|
event.preventDefault();
|
|
@@ -338,11 +267,14 @@ window.__ModuleLoader__.load({
|
|
|
338
267
|
className: `${SubagentHeaderLineage_module_css_default.disclosure} ${isExpanded ? SubagentHeaderLineage_module_css_default.disclosureOpen : ""}`,
|
|
339
268
|
"aria-label": t(isExpanded ? "branch.collapse" : "branch.expand", { label }),
|
|
340
269
|
onClick: toggle,
|
|
341
|
-
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.
|
|
270
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular, {})
|
|
342
271
|
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
343
272
|
className: SubagentHeaderLineage_module_css_default.clickarea,
|
|
344
273
|
children: [
|
|
345
|
-
(0, react_jsx_runtime.jsx)(
|
|
274
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
275
|
+
className: SubagentHeaderLineage_module_css_default.rowActivitySlot,
|
|
276
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: entry.activity === "running" ? "ongoing" : completed ? "done" : "idle" })
|
|
277
|
+
}),
|
|
346
278
|
(0, react_jsx_runtime.jsxs)("span", {
|
|
347
279
|
className: SubagentHeaderLineage_module_css_default.content,
|
|
348
280
|
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
@@ -363,6 +295,17 @@ window.__ModuleLoader__.load({
|
|
|
363
295
|
title: t("duration.exactTitle", { duration: durationMetric.exact }),
|
|
364
296
|
children: durationMetric.compact
|
|
365
297
|
})]
|
|
298
|
+
}),
|
|
299
|
+
!isCurrent && (0, react_jsx_runtime.jsx)("button", {
|
|
300
|
+
type: "button",
|
|
301
|
+
className: SubagentHeaderLineage_module_css_default.sidebarButton,
|
|
302
|
+
"aria-label": t("open.sidebar", { label }),
|
|
303
|
+
title: t("open.sidebar", { label }),
|
|
304
|
+
onClick: openAside,
|
|
305
|
+
onKeyDown: (event) => {
|
|
306
|
+
event.stopPropagation();
|
|
307
|
+
},
|
|
308
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular, {})
|
|
366
309
|
})
|
|
367
310
|
]
|
|
368
311
|
})]
|
|
@@ -370,12 +313,7 @@ window.__ModuleLoader__.load({
|
|
|
370
313
|
role: "group",
|
|
371
314
|
className: SubagentHeaderLineage_module_css_default.children,
|
|
372
315
|
"aria-busy": childLoading || void 0,
|
|
373
|
-
children: childCatalog === void 0 ? (0, react_jsx_runtime.jsx)(CatalogLoadingRows, {
|
|
374
|
-
parentSessionId: entry.id,
|
|
375
|
-
summaries,
|
|
376
|
-
level: level + 1,
|
|
377
|
-
t
|
|
378
|
-
}) : (0, react_jsx_runtime.jsx)(CatalogRows, {
|
|
316
|
+
children: childCatalog === void 0 ? (0, react_jsx_runtime.jsx)(CatalogLoadingRows, { t }) : (0, react_jsx_runtime.jsx)(CatalogRows, {
|
|
379
317
|
parentSessionId: entry.id,
|
|
380
318
|
currentSessionId,
|
|
381
319
|
catalog: childCatalog,
|
|
@@ -383,9 +321,9 @@ window.__ModuleLoader__.load({
|
|
|
383
321
|
summaries,
|
|
384
322
|
expanded,
|
|
385
323
|
level: level + 1,
|
|
386
|
-
now,
|
|
387
324
|
openChild,
|
|
388
|
-
|
|
325
|
+
openChildAside,
|
|
326
|
+
refreshProjection,
|
|
389
327
|
toggleBranch,
|
|
390
328
|
closeCatalog,
|
|
391
329
|
t
|
|
@@ -406,46 +344,44 @@ window.__ModuleLoader__.load({
|
|
|
406
344
|
};
|
|
407
345
|
}
|
|
408
346
|
/** One trigger-plus-tree dropdown over the catalog rooted at `rootSessionId`. */
|
|
409
|
-
function CatalogDropdown({ rootSessionId, currentSessionId, displayTitle, openTitle, variant,
|
|
347
|
+
function CatalogDropdown({ rootSessionId, currentSessionId, displayTitle, openTitle, variant, useSessions, useSessionStatus, openChild, openChildAside, refreshProjection, t }) {
|
|
410
348
|
const ancestorSwitcher = variant === "switcher" && openTitle !== void 0;
|
|
411
|
-
const
|
|
349
|
+
const projections = useSessions((state) => state.projectionsBySession);
|
|
412
350
|
const summaries = useSessions((state) => state.byId);
|
|
351
|
+
const statuses = useSessionStatus((value) => value);
|
|
352
|
+
const catalogs = (0, react.useMemo)(() => Object.fromEntries(Object.entries(projections).map(([id, snapshot]) => [id, {
|
|
353
|
+
state: snapshot.state === "idle" ? snapshot.values.subagentCatalog === void 0 ? "loading" : "ready" : snapshot.state,
|
|
354
|
+
error: snapshot.error,
|
|
355
|
+
entries: (snapshot.values.subagentCatalog ?? []).map((entry) => ({
|
|
356
|
+
...entry,
|
|
357
|
+
activity: (statuses.get(entry.id)?.running ?? summaries[entry.id]?.running) === true ? "running" : "inactive"
|
|
358
|
+
}))
|
|
359
|
+
}])), [
|
|
360
|
+
projections,
|
|
361
|
+
summaries,
|
|
362
|
+
statuses
|
|
363
|
+
]);
|
|
413
364
|
const catalog = catalogs[rootSessionId];
|
|
414
365
|
const [open, setOpen] = (0, react.useState)(false);
|
|
415
366
|
const [menuPosition, setMenuPosition] = (0, react.useState)();
|
|
416
|
-
const [now, setNow] = (0, react.useState)(() => Date.now());
|
|
417
367
|
const [expanded, setExpanded] = (0, react.useState)(() => /* @__PURE__ */ new Set());
|
|
418
368
|
const rootRef = (0, react.useRef)(null);
|
|
419
369
|
const triggerRef = (0, react.useRef)(null);
|
|
420
370
|
const menuRef = (0, react.useRef)(null);
|
|
421
371
|
const hoverOpenTimer = (0, react.useRef)(void 0);
|
|
422
372
|
const hoverCloseTimer = (0, react.useRef)(void 0);
|
|
423
|
-
const
|
|
424
|
-
const
|
|
425
|
-
|
|
426
|
-
const
|
|
427
|
-
const
|
|
428
|
-
const
|
|
429
|
-
const
|
|
430
|
-
const
|
|
431
|
-
const totalCountKey = descendantCount === 1 ? "count.total.one" : "count.total.other";
|
|
432
|
-
const runningCountKey = descendants.runningCount === 1 ? "count.running.one" : "count.running.other";
|
|
433
|
-
const presentedCatalog = (descendants.count > 0 || variant === "switcher") && (catalog === void 0 || catalog.state === "ready" && catalog.entries.length === 0) ? {
|
|
373
|
+
const currentEntry = currentSessionId === void 0 ? void 0 : catalog?.entries.find((entry) => entry.id === currentSessionId);
|
|
374
|
+
const switcherDisplayTitle = currentEntry !== void 0 ? currentEntry.label ?? currentEntry.id : displayTitle;
|
|
375
|
+
const directChildren = catalog?.entries ?? [];
|
|
376
|
+
const directCount = directChildren.length;
|
|
377
|
+
const runningCount = directChildren.filter((entry) => entry.activity === "running").length;
|
|
378
|
+
const totalCountKey = directCount === 1 ? "count.total.one" : "count.total.other";
|
|
379
|
+
const runningCountKey = runningCount === 1 ? "count.running.one" : "count.running.other";
|
|
380
|
+
const presentedCatalog = catalog ?? (variant === "switcher" ? {
|
|
434
381
|
entries: [],
|
|
435
|
-
parentAvailable: catalog?.parentAvailable ?? false,
|
|
436
382
|
state: "loading",
|
|
437
383
|
error: null
|
|
438
|
-
} :
|
|
439
|
-
const observeCatalog = (parentSessionId, next) => {
|
|
440
|
-
if (next) observedCatalogs.current.add(parentSessionId);
|
|
441
|
-
else observedCatalogs.current.delete(parentSessionId);
|
|
442
|
-
setCatalogOpen(parentSessionId, next);
|
|
443
|
-
};
|
|
444
|
-
const closeAllCatalogs = () => {
|
|
445
|
-
for (const parentSessionId of observedCatalogs.current) setCatalogOpen(parentSessionId, false);
|
|
446
|
-
observedCatalogs.current.clear();
|
|
447
|
-
setExpanded(/* @__PURE__ */ new Set());
|
|
448
|
-
};
|
|
384
|
+
} : void 0);
|
|
449
385
|
const cancelHoverClose = () => {
|
|
450
386
|
if (hoverCloseTimer.current === void 0) return;
|
|
451
387
|
clearTimeout(hoverCloseTimer.current);
|
|
@@ -465,12 +401,10 @@ window.__ModuleLoader__.load({
|
|
|
465
401
|
if (trigger === null) return;
|
|
466
402
|
setOpen(true);
|
|
467
403
|
setMenuPosition(catalogMenuPosition(trigger));
|
|
468
|
-
setNow(Date.now());
|
|
469
|
-
observeCatalog(rootSessionId, true);
|
|
470
404
|
} else {
|
|
471
405
|
setOpen(false);
|
|
472
406
|
setMenuPosition(void 0);
|
|
473
|
-
|
|
407
|
+
setExpanded(/* @__PURE__ */ new Set());
|
|
474
408
|
}
|
|
475
409
|
if (restoreFocus) queueMicrotask(() => {
|
|
476
410
|
triggerRef.current?.focus();
|
|
@@ -499,10 +433,9 @@ window.__ModuleLoader__.load({
|
|
|
499
433
|
if (closing.has(parentSessionId) || !expanded.has(parentSessionId)) return;
|
|
500
434
|
closing.add(parentSessionId);
|
|
501
435
|
const branch = catalogs[parentSessionId];
|
|
502
|
-
for (const entry of branch?.entries ?? [])
|
|
436
|
+
for (const entry of branch?.entries ?? []) visit(entry.id);
|
|
503
437
|
};
|
|
504
438
|
visit(root);
|
|
505
|
-
for (const parentSessionId of closing) observeCatalog(parentSessionId, false);
|
|
506
439
|
setExpanded((current) => new Set([...current].filter((id) => !closing.has(id))));
|
|
507
440
|
};
|
|
508
441
|
const toggleBranch = (childSessionId) => {
|
|
@@ -511,7 +444,7 @@ window.__ModuleLoader__.load({
|
|
|
511
444
|
return;
|
|
512
445
|
}
|
|
513
446
|
setExpanded((current) => new Set(current).add(childSessionId));
|
|
514
|
-
|
|
447
|
+
refreshProjection(childSessionId);
|
|
515
448
|
};
|
|
516
449
|
(0, react.useEffect)(() => {
|
|
517
450
|
if (!open) return;
|
|
@@ -538,29 +471,18 @@ window.__ModuleLoader__.load({
|
|
|
538
471
|
document.removeEventListener("scroll", placeMenu, true);
|
|
539
472
|
};
|
|
540
473
|
}, [open]);
|
|
541
|
-
(0, react.useEffect)(() => {
|
|
542
|
-
if (!open || descendants.runningCount === 0) return;
|
|
543
|
-
const timer = setInterval(() => {
|
|
544
|
-
setNow(Date.now());
|
|
545
|
-
}, 1e3);
|
|
546
|
-
return () => {
|
|
547
|
-
clearInterval(timer);
|
|
548
|
-
};
|
|
549
|
-
}, [open, descendants.runningCount]);
|
|
550
474
|
(0, react.useEffect)(() => () => {
|
|
551
475
|
cancelHoverOpen();
|
|
552
476
|
cancelHoverClose();
|
|
553
|
-
for (const parentSessionId of observedCatalogs.current) setCatalogOpenRef.current(parentSessionId, false);
|
|
554
|
-
observedCatalogs.current.clear();
|
|
555
477
|
}, []);
|
|
556
|
-
const visible = presentedCatalog !== void 0 && (variant === "switcher" || presentedCatalog.state === "error" || presentedCatalog.entries.length > 0
|
|
478
|
+
const visible = presentedCatalog !== void 0 && (variant === "switcher" || presentedCatalog.state === "error" || presentedCatalog.entries.length > 0);
|
|
557
479
|
(0, react.useEffect)(() => {
|
|
558
480
|
if (visible) return;
|
|
559
481
|
cancelHoverOpen();
|
|
560
482
|
cancelHoverClose();
|
|
561
483
|
if (!open) return;
|
|
562
484
|
setOpen(false);
|
|
563
|
-
|
|
485
|
+
setExpanded(/* @__PURE__ */ new Set());
|
|
564
486
|
}, [visible, open]);
|
|
565
487
|
if (!visible) return null;
|
|
566
488
|
const focusAt = (index) => {
|
|
@@ -594,94 +516,105 @@ window.__ModuleLoader__.load({
|
|
|
594
516
|
onKeyDown: navigate,
|
|
595
517
|
onMouseEnter: scheduleHoverOpen,
|
|
596
518
|
onMouseLeave: scheduleHoverClose,
|
|
597
|
-
children: [
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
519
|
+
children: [(0, react_jsx_runtime.jsxs)("button", {
|
|
520
|
+
ref: triggerRef,
|
|
521
|
+
type: "button",
|
|
522
|
+
className: variant === "switcher" ? `${SubagentHeaderLineage_module_css_default.switcherTrigger} ${ancestorSwitcher ? SubagentHeaderLineage_module_css_default.ancestorSwitcherTrigger : ""}` : SubagentHeaderLineage_module_css_default.trigger,
|
|
523
|
+
"aria-haspopup": "tree",
|
|
524
|
+
"aria-expanded": open,
|
|
525
|
+
"aria-label": variant === "switcher" ? t("switcher.aria", { title: switcherDisplayTitle }) : t(runningCount > 0 ? runningCountKey : totalCountKey, { count: runningCount > 0 ? runningCount : directCount }),
|
|
526
|
+
onClick: openTitle === void 0 ? void 0 : () => {
|
|
527
|
+
cancelHoverOpen();
|
|
528
|
+
if (open) changeOpen(false);
|
|
529
|
+
openTitle();
|
|
530
|
+
},
|
|
531
|
+
onKeyDown: (event) => {
|
|
532
|
+
if (event.key !== "ArrowDown") return;
|
|
533
|
+
event.preventDefault();
|
|
534
|
+
if (!open) changeOpen(true);
|
|
535
|
+
queueMicrotask(() => {
|
|
536
|
+
focusAt(0);
|
|
537
|
+
});
|
|
538
|
+
},
|
|
539
|
+
children: [variant === "switcher" ? (0, react_jsx_runtime.jsx)("span", {
|
|
540
|
+
className: SubagentHeaderLineage_module_css_default.switcherTitle,
|
|
541
|
+
children: switcherDisplayTitle
|
|
542
|
+
}) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [runningCount > 0 && (0, react_jsx_runtime.jsx)("span", {
|
|
543
|
+
className: SubagentHeaderLineage_module_css_default.activitySlot,
|
|
544
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "ongoing" })
|
|
545
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
546
|
+
className: SubagentHeaderLineage_module_css_default.count,
|
|
547
|
+
children: t(totalCountKey, { count: directCount })
|
|
548
|
+
})] }), variant === "switcher" ? (0, react_jsx_runtime.jsx)(SubagentSwitcherIcon, {}) : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, { className: open ? SubagentHeaderLineage_module_css_default.triggerOpen : void 0 })]
|
|
549
|
+
}), open && (0, react_dom.createPortal)((0, react_jsx_runtime.jsx)("div", {
|
|
550
|
+
ref: menuRef,
|
|
551
|
+
className: SubagentHeaderLineage_module_css_default.menu,
|
|
552
|
+
style: menuPosition,
|
|
553
|
+
role: "tree",
|
|
554
|
+
"aria-label": t("tree.aria"),
|
|
555
|
+
onMouseEnter: cancelHoverClose,
|
|
556
|
+
onMouseLeave: scheduleHoverClose,
|
|
557
|
+
children: (0, react_jsx_runtime.jsx)(CatalogRows, {
|
|
558
|
+
parentSessionId: rootSessionId,
|
|
559
|
+
currentSessionId,
|
|
560
|
+
catalog: presentedCatalog,
|
|
561
|
+
catalogs,
|
|
562
|
+
summaries,
|
|
563
|
+
expanded,
|
|
564
|
+
level: 1,
|
|
565
|
+
openChild,
|
|
566
|
+
openChildAside,
|
|
567
|
+
refreshProjection,
|
|
568
|
+
toggleBranch,
|
|
569
|
+
closeCatalog: () => {
|
|
570
|
+
changeOpen(false);
|
|
621
571
|
},
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
}) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [descendants.runningCount > 0 && (0, react_jsx_runtime.jsx)("span", {
|
|
626
|
-
className: SubagentHeaderLineage_module_css_default.activitySlot,
|
|
627
|
-
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "ongoing" })
|
|
628
|
-
}), (0, react_jsx_runtime.jsx)("span", {
|
|
629
|
-
className: SubagentHeaderLineage_module_css_default.count,
|
|
630
|
-
children: t(totalCountKey, { count: descendantCount })
|
|
631
|
-
})] }), variant === "switcher" ? (0, react_jsx_runtime.jsx)(SubagentSwitcherIcon, {}) : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { className: open ? SubagentHeaderLineage_module_css_default.triggerOpen : void 0 })]
|
|
632
|
-
}),
|
|
633
|
-
open && (0, react_dom.createPortal)((0, react_jsx_runtime.jsx)("div", {
|
|
634
|
-
ref: menuRef,
|
|
635
|
-
className: SubagentHeaderLineage_module_css_default.menu,
|
|
636
|
-
style: menuPosition,
|
|
637
|
-
role: "tree",
|
|
638
|
-
"aria-label": t("tree.aria"),
|
|
639
|
-
onMouseEnter: cancelHoverClose,
|
|
640
|
-
onMouseLeave: scheduleHoverClose,
|
|
641
|
-
children: (0, react_jsx_runtime.jsx)(CatalogRows, {
|
|
642
|
-
parentSessionId: rootSessionId,
|
|
643
|
-
currentSessionId,
|
|
644
|
-
catalog: presentedCatalog,
|
|
645
|
-
catalogs,
|
|
646
|
-
summaries,
|
|
647
|
-
expanded,
|
|
648
|
-
level: 1,
|
|
649
|
-
now,
|
|
650
|
-
openChild,
|
|
651
|
-
refresh,
|
|
652
|
-
toggleBranch,
|
|
653
|
-
closeCatalog: () => {
|
|
654
|
-
changeOpen(false);
|
|
655
|
-
},
|
|
656
|
-
t
|
|
657
|
-
})
|
|
658
|
-
}), document.body)
|
|
659
|
-
]
|
|
572
|
+
t
|
|
573
|
+
})
|
|
574
|
+
}), document.body)]
|
|
660
575
|
});
|
|
661
576
|
}
|
|
662
577
|
/**
|
|
578
|
+
* Session-header catalog action for root sessions: the descendant count and
|
|
579
|
+
* its dropdown, ordered after the task list. Child sessions render nothing
|
|
580
|
+
* here — their breadcrumb switcher in the lineage slot owns the same
|
|
581
|
+
* navigation.
|
|
582
|
+
* @param props - Session standard props plus the catalog actions and translator.
|
|
583
|
+
* @returns The count dropdown, or null on a child session.
|
|
584
|
+
*/
|
|
585
|
+
function SubagentCatalogAction({ sessionId, useSessions, useSessionStatus, openChild, openChildAside, refreshProjection, t }) {
|
|
586
|
+
if (useSessions((state) => state.byId[sessionId]?.origin === "subagent")) return null;
|
|
587
|
+
return (0, react_jsx_runtime.jsx)(CatalogDropdown, {
|
|
588
|
+
rootSessionId: sessionId,
|
|
589
|
+
variant: "count",
|
|
590
|
+
useSessions,
|
|
591
|
+
useSessionStatus,
|
|
592
|
+
openChild,
|
|
593
|
+
openChildAside,
|
|
594
|
+
refreshProjection,
|
|
595
|
+
t
|
|
596
|
+
}, sessionId);
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
663
599
|
* Render one breadcrumb title together with its subagent navigation.
|
|
664
600
|
* @param props - Breadcrumb title, session standard props, and catalog actions.
|
|
665
|
-
* @returns
|
|
601
|
+
* @returns A title-and-chevron sibling switcher, or nothing on a root session.
|
|
666
602
|
*/
|
|
667
|
-
function SubagentHeaderLineage({ lineageSessionId, displayTitle, openTitle, useSessions, openChild,
|
|
603
|
+
function SubagentHeaderLineage({ lineageSessionId, displayTitle, openTitle, useSessions, useSession, useSessionStatus, openChild, openChildAside, refreshProjection, t }) {
|
|
604
|
+
const address = useSession((session) => session.subagent?.address);
|
|
668
605
|
const parentId = useSessions((state) => {
|
|
669
|
-
|
|
670
|
-
|
|
606
|
+
if (address?.childSessionId === lineageSessionId) return address.parentSessionId;
|
|
607
|
+
for (const [parentId, snapshot] of Object.entries(state.projectionsBySession)) if (snapshot.values.subagentCatalog?.some((entry) => entry.id === lineageSessionId)) return parentId;
|
|
671
608
|
});
|
|
672
609
|
const shared = {
|
|
673
610
|
useSessions,
|
|
611
|
+
useSessionStatus,
|
|
674
612
|
openChild,
|
|
675
|
-
|
|
676
|
-
|
|
613
|
+
openChildAside,
|
|
614
|
+
refreshProjection,
|
|
677
615
|
t
|
|
678
616
|
};
|
|
679
|
-
if (parentId === void 0) return
|
|
680
|
-
rootSessionId: lineageSessionId,
|
|
681
|
-
variant: "count",
|
|
682
|
-
separator: true,
|
|
683
|
-
...shared
|
|
684
|
-
}, lineageSessionId);
|
|
617
|
+
if (parentId === void 0) return null;
|
|
685
618
|
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(CatalogDropdown, {
|
|
686
619
|
rootSessionId: parentId,
|
|
687
620
|
currentSessionId: lineageSessionId,
|
|
@@ -697,13 +630,13 @@ window.__ModuleLoader__.load({
|
|
|
697
630
|
}
|
|
698
631
|
//#endregion
|
|
699
632
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-subagent/src/client/SubagentReadOnlyComposer.module.css.mjs
|
|
700
|
-
const css = ".XJ7liG_frame{border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-bg-layer-1);min-height:54px;color:var(--dsw-alias-label-tertiary);border-radius:14px;justify-content:center;align-items:center;gap:8px;margin:0 24px 20px;padding:10px 16px;font-size:13px;line-height:20px;display:flex}.XJ7liG_frame strong{color:var(--dsw-alias-label-primary);font-weight:510}";
|
|
701
|
-
const tagId = "@deepseek-ai/dsh-client-ui-subagent/SubagentReadOnlyComposer.module.css";
|
|
702
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
633
|
+
const css$1 = ".XJ7liG_frame{border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-bg-layer-1);min-height:54px;color:var(--dsw-alias-label-tertiary);border-radius:14px;justify-content:center;align-items:center;gap:8px;margin:0 24px 20px;padding:10px 16px;font-size:13px;line-height:20px;display:flex}.XJ7liG_frame strong{color:var(--dsw-alias-label-primary);font-weight:510}";
|
|
634
|
+
const tagId$1 = "@deepseek-ai/dsh-client-ui-subagent/SubagentReadOnlyComposer.module.css";
|
|
635
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
703
636
|
const tag = document.createElement("style");
|
|
704
637
|
tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-subagent";
|
|
705
|
-
tag.dataset.pluginCss = tagId;
|
|
706
|
-
tag.textContent = css;
|
|
638
|
+
tag.dataset.pluginCss = tagId$1;
|
|
639
|
+
tag.textContent = css$1;
|
|
707
640
|
document.head.appendChild(tag);
|
|
708
641
|
}
|
|
709
642
|
var SubagentReadOnlyComposer_module_css_default = { "frame": "XJ7liG_frame" };
|
|
@@ -719,9 +652,163 @@ window.__ModuleLoader__.load({
|
|
|
719
652
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
720
653
|
className: SubagentReadOnlyComposer_module_css_default.frame,
|
|
721
654
|
role: "status",
|
|
722
|
-
children: [(0, react_jsx_runtime.jsx)("strong", { children: t(oneShot ? "readonly.oneShot.title" : "readonly.title") }), (0, react_jsx_runtime.jsx)("span", { children: t(oneShot ? "readonly.oneShot.body" : "readonly.body") })]
|
|
655
|
+
children: [(0, react_jsx_runtime.jsx)("strong", { children: t(oneShot ? "readonly.oneShot.title" : "readonly.title") }), (0, react_jsx_runtime.jsx)("span", { children: t(matched.reason === "unknown" ? "readonly.unknown.body" : oneShot ? "readonly.oneShot.body" : "readonly.body") })]
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
//#endregion
|
|
659
|
+
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-subagent/src/client/sidebar-chat/SidebarChat.module.css.mjs
|
|
660
|
+
const css = ".olTFqa_root{width:100%;min-width:0;height:100%;min-height:0;display:flex}";
|
|
661
|
+
const tagId = "@deepseek-ai/dsh-client-ui-subagent/SidebarChat.module.css";
|
|
662
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
663
|
+
const tag = document.createElement("style");
|
|
664
|
+
tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-subagent";
|
|
665
|
+
tag.dataset.pluginCss = tagId;
|
|
666
|
+
tag.textContent = css;
|
|
667
|
+
document.head.appendChild(tag);
|
|
668
|
+
}
|
|
669
|
+
var SidebarChat_module_css_default = { "root": "olTFqa_root" };
|
|
670
|
+
//#endregion
|
|
671
|
+
//#region lib/types/client/sidebar-chat/index.js
|
|
672
|
+
/** Stable implementation identity for the Sidebar tab body. */
|
|
673
|
+
const SUBAGENT_CHAT_ID = "@deepseek-ai/dsh-client-ui-subagent";
|
|
674
|
+
/** Resource-address prefix for an embedded Session chat. */
|
|
675
|
+
const SUBAGENT_CHAT_ADDRESS = "dsh-resource://subagentchat/session/";
|
|
676
|
+
/**
|
|
677
|
+
* Address one subagent Session together with the routing facts needed to restore it.
|
|
678
|
+
* @param address - durable direct-parent subagent address.
|
|
679
|
+
* @returns canonical Sidebar resource address.
|
|
680
|
+
*/
|
|
681
|
+
function subagentChatAddress(address) {
|
|
682
|
+
const query = new URLSearchParams({
|
|
683
|
+
parent: address.parentSessionId,
|
|
684
|
+
mode: address.mode
|
|
685
|
+
});
|
|
686
|
+
return `${SUBAGENT_CHAT_ADDRESS}${encodeURIComponent(address.childSessionId)}?${query}`;
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Parse one canonical Sidebar chat resource address.
|
|
690
|
+
* @param value - possible chat resource address.
|
|
691
|
+
* @returns the encoded direct-parent address, or undefined for another or malformed resource.
|
|
692
|
+
*/
|
|
693
|
+
function parseSubagentChatAddress(value) {
|
|
694
|
+
let url;
|
|
695
|
+
try {
|
|
696
|
+
url = new URL(value);
|
|
697
|
+
} catch (_invalidUrl) {
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
if (url.protocol !== "dsh-resource:" || url.hostname.toLowerCase() !== "subagentchat") return void 0;
|
|
701
|
+
const parts = url.pathname.split("/").filter(Boolean);
|
|
702
|
+
if (parts.length !== 2 || parts[0] !== "session") return void 0;
|
|
703
|
+
const parentSessionId = url.searchParams.get("parent");
|
|
704
|
+
const mode = url.searchParams.get("mode");
|
|
705
|
+
if (parentSessionId === null || parentSessionId === "" || mode !== "one-shot" && mode !== "continuable" && mode !== "unknown") return;
|
|
706
|
+
try {
|
|
707
|
+
return {
|
|
708
|
+
parentSessionId,
|
|
709
|
+
childSessionId: decodeURIComponent(parts[1]),
|
|
710
|
+
mode
|
|
711
|
+
};
|
|
712
|
+
} catch (_invalidEncoding) {
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
function waitForAbort(signal) {
|
|
717
|
+
if (signal.aborted) return Promise.resolve();
|
|
718
|
+
return new Promise((resolve) => {
|
|
719
|
+
signal.addEventListener("abort", () => {
|
|
720
|
+
resolve();
|
|
721
|
+
}, { once: true });
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
function isAbortRequested(signal) {
|
|
725
|
+
return signal.aborted;
|
|
726
|
+
}
|
|
727
|
+
function subagentChatResourceProvider(sessions) {
|
|
728
|
+
return {
|
|
729
|
+
protocol: "subagentchat",
|
|
730
|
+
async *open(resourceAddress, { signal }) {
|
|
731
|
+
const address = parseSubagentChatAddress(resourceAddress);
|
|
732
|
+
if (address === void 0) throw new Error(`ui-subagent: invalid chat resource address "${resourceAddress}"`);
|
|
733
|
+
if (isAbortRequested(signal)) return;
|
|
734
|
+
const reference = sessions.retain(address, {
|
|
735
|
+
source: "sidebarChat",
|
|
736
|
+
signal
|
|
737
|
+
});
|
|
738
|
+
try {
|
|
739
|
+
yield {
|
|
740
|
+
ok: true,
|
|
741
|
+
value: {
|
|
742
|
+
address,
|
|
743
|
+
reference
|
|
744
|
+
}
|
|
745
|
+
};
|
|
746
|
+
await waitForAbort(signal);
|
|
747
|
+
} finally {
|
|
748
|
+
reference.release();
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
/** Fixed Chat selection used by an embedded Conversation occurrence. */
|
|
754
|
+
function FixedChatConversationView(props) {
|
|
755
|
+
return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: props.renderSlot("conversation.session", { view: "chat" }) });
|
|
756
|
+
}
|
|
757
|
+
/** Render the shared Conversation content for one explicitly provided child Session. */
|
|
758
|
+
function ConversationSlotPanel({ sessionId, useSession, useConversation, useSessions, renderFactorySlot }) {
|
|
759
|
+
const session = useSession((value) => value);
|
|
760
|
+
const shellPhase = useConversation((value) => value).activeTargets.size > 0 || !session.blank && !session.awaitingFirstTurn || session.running ? "active" : session.promptAttempted ? "engaging" : "blank";
|
|
761
|
+
const summaryBlank = useSessions((state) => state.byId[sessionId]?.blank);
|
|
762
|
+
const parentAvailabilityPending = session.subagent?.address.mode === "continuable" && session.subagent.parentAvailable === void 0;
|
|
763
|
+
const settling = shellPhase === "blank" && session.openState === "loading" && summaryBlank !== true || parentAvailabilityPending;
|
|
764
|
+
const hero = shellPhase === "blank" && (session.openState === "open" || summaryBlank === true);
|
|
765
|
+
return renderFactorySlot("conversation.content", {
|
|
766
|
+
variant: "embedded",
|
|
767
|
+
phase: settling ? "settling" : hero ? "hero" : "active",
|
|
768
|
+
hero
|
|
769
|
+
}, { slots: { views: FixedChatConversationView } });
|
|
770
|
+
}
|
|
771
|
+
/** Bind a chat resource's child reference around its Conversation slot. */
|
|
772
|
+
function SidebarChatTab({ useResource, useTabInfo, SessionProvider, renderSlot }) {
|
|
773
|
+
const { tab } = useTabInfo();
|
|
774
|
+
const resource = useResource(tab.contentId);
|
|
775
|
+
return (0, react_jsx_runtime.jsx)("div", {
|
|
776
|
+
className: SidebarChat_module_css_default.root,
|
|
777
|
+
"data-sidebar-chat": "",
|
|
778
|
+
children: resource.value === void 0 ? null : (0, react_jsx_runtime.jsx)(SessionProvider, {
|
|
779
|
+
session: resource.value.reference,
|
|
780
|
+
children: renderSlot("sidebar.chat.conversation", {})
|
|
781
|
+
})
|
|
723
782
|
});
|
|
724
783
|
}
|
|
784
|
+
/**
|
|
785
|
+
* Register the chat resource owner and its right-Sidebar presentation.
|
|
786
|
+
* @param ctx - Client root carrying Sessions, resources, Slots, and Sidebar registries.
|
|
787
|
+
* @param t - Chat namespace translator used for fallback tab titles.
|
|
788
|
+
*/
|
|
789
|
+
function registerSidebarChat(ctx, t) {
|
|
790
|
+
ctx.effect(() => ctx.resources.register(subagentChatResourceProvider(ctx.sessions)), "ui-subagent: Sidebar chat resources");
|
|
791
|
+
ctx.effect(() => ctx.sidebarRightTabs.register({
|
|
792
|
+
id: SUBAGENT_CHAT_ID,
|
|
793
|
+
kind: "subagentchat",
|
|
794
|
+
patterns: [`${SUBAGENT_CHAT_ADDRESS}**`],
|
|
795
|
+
priority: "builtin",
|
|
796
|
+
canOpen: (address) => parseSubagentChatAddress(address) !== void 0,
|
|
797
|
+
title: (address) => {
|
|
798
|
+
const child = parseSubagentChatAddress(address)?.childSessionId;
|
|
799
|
+
return child === void 0 ? t("sidebar.chat") : ctx.sessions.list.getSnapshot().byId[child]?.projectionValues?.subagent?.label ?? child;
|
|
800
|
+
}
|
|
801
|
+
}), "ui-subagent: Sidebar chat type");
|
|
802
|
+
ctx.effect(() => ctx.slots.inject("sidebar.right.pane.tab", () => ctx.slots.register({
|
|
803
|
+
name: "sidebar.right.pane.tab",
|
|
804
|
+
key: SUBAGENT_CHAT_ID,
|
|
805
|
+
children: { "sidebar.chat.conversation": {
|
|
806
|
+
kind: "single",
|
|
807
|
+
scope: "session"
|
|
808
|
+
} }
|
|
809
|
+
}, SidebarChatTab)), "ui-subagent: Sidebar chat body");
|
|
810
|
+
ctx.effect(() => ctx.slots.inject("sidebar.chat.conversation", () => ctx.slots.register({ name: "sidebar.chat.conversation" }, ConversationSlotPanel)), "ui-subagent: Sidebar Conversation");
|
|
811
|
+
}
|
|
725
812
|
//#endregion
|
|
726
813
|
//#region lib/types/client/locales.js
|
|
727
814
|
/** `subagent` namespace dictionaries. */
|
|
@@ -729,9 +816,6 @@ window.__ModuleLoader__.load({
|
|
|
729
816
|
const NS = "subagent";
|
|
730
817
|
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
731
818
|
const zh = {
|
|
732
|
-
"diagnostic.corrupt": "会话记录损坏",
|
|
733
|
-
"diagnostic.unsupported": "子代理记录版本不受支持",
|
|
734
|
-
"diagnostic.unavailable": "会话记录暂不可用",
|
|
735
819
|
"duration.seconds": "{seconds}秒",
|
|
736
820
|
"duration.minutes": "{minutes}分{seconds}秒",
|
|
737
821
|
"duration.hours": "{hours}小时{minutes}分{seconds}秒",
|
|
@@ -747,12 +831,14 @@ window.__ModuleLoader__.load({
|
|
|
747
831
|
"tokens.million": "{value}M",
|
|
748
832
|
"tokens.total": "{value} tok",
|
|
749
833
|
"loading.label": "正在加载子代理…",
|
|
750
|
-
"loading.aria": "正在加载子代理",
|
|
751
834
|
"load.error": "无法加载子代理",
|
|
752
835
|
"retry": "重试",
|
|
753
836
|
"mode.oneShot": "一次性",
|
|
754
837
|
"mode.continuable": "可继续",
|
|
838
|
+
"mode.unknown": "模式未知",
|
|
839
|
+
"readonly.unknown.body": "读取子会话后才能确定是否可继续。",
|
|
755
840
|
"activity.running": "正在运行",
|
|
841
|
+
"activity.completed": "已完成",
|
|
756
842
|
"activity.inactive": "当前未运行",
|
|
757
843
|
"branch.collapse": "收起 {label} 的下级子代理",
|
|
758
844
|
"branch.expand": "展开 {label} 的下级子代理",
|
|
@@ -762,6 +848,8 @@ window.__ModuleLoader__.load({
|
|
|
762
848
|
"count.running.other": "{count} 个子代理,正在运行",
|
|
763
849
|
"switcher.aria": "切换子代理:{title}",
|
|
764
850
|
"tree.aria": "子代理会话",
|
|
851
|
+
"open.sidebar": "在侧边栏打开 {label}",
|
|
852
|
+
"sidebar.chat": "聊天",
|
|
765
853
|
"readonly.oneShot.title": "一次性子代理记录",
|
|
766
854
|
"readonly.title": "此子代理暂时只读",
|
|
767
855
|
"readonly.oneShot.body": "一次性任务不支持后续消息,可在这里查看完整执行记录。",
|
|
@@ -769,9 +857,6 @@ window.__ModuleLoader__.load({
|
|
|
769
857
|
};
|
|
770
858
|
/** English dictionary, key-identical to the Chinese source of truth. */
|
|
771
859
|
const en = {
|
|
772
|
-
"diagnostic.corrupt": "corrupted session record",
|
|
773
|
-
"diagnostic.unsupported": "unsupported subagent record version",
|
|
774
|
-
"diagnostic.unavailable": "session record temporarily unavailable",
|
|
775
860
|
"duration.seconds": "{seconds}s",
|
|
776
861
|
"duration.minutes": "{minutes}m {seconds}s",
|
|
777
862
|
"duration.hours": "{hours}h {minutes}m {seconds}s",
|
|
@@ -787,12 +872,14 @@ window.__ModuleLoader__.load({
|
|
|
787
872
|
"tokens.million": "{value}M",
|
|
788
873
|
"tokens.total": "{value} tok",
|
|
789
874
|
"loading.label": "Loading subagents…",
|
|
790
|
-
"loading.aria": "Loading subagents",
|
|
791
875
|
"load.error": "Unable to load subagents",
|
|
792
876
|
"retry": "Retry",
|
|
793
877
|
"mode.oneShot": "one-shot",
|
|
794
878
|
"mode.continuable": "continuable",
|
|
879
|
+
"mode.unknown": "unknown mode",
|
|
880
|
+
"readonly.unknown.body": "Read the child session to determine whether it can be continued.",
|
|
795
881
|
"activity.running": "running",
|
|
882
|
+
"activity.completed": "completed",
|
|
796
883
|
"activity.inactive": "not running",
|
|
797
884
|
"branch.collapse": "Collapse {label} descendants",
|
|
798
885
|
"branch.expand": "Expand {label} descendants",
|
|
@@ -802,6 +889,8 @@ window.__ModuleLoader__.load({
|
|
|
802
889
|
"count.running.other": "{count} subagents running",
|
|
803
890
|
"switcher.aria": "Switch subagent: {title}",
|
|
804
891
|
"tree.aria": "Subagent sessions",
|
|
892
|
+
"open.sidebar": "Open {label} in sidebar",
|
|
893
|
+
"sidebar.chat": "Chat",
|
|
805
894
|
"readonly.oneShot.title": "One-shot subagent record",
|
|
806
895
|
"readonly.title": "This subagent is read-only for now",
|
|
807
896
|
"readonly.oneShot.body": "One-shot tasks do not accept follow-ups; review the full execution record here.",
|
|
@@ -809,16 +898,19 @@ window.__ModuleLoader__.load({
|
|
|
809
898
|
};
|
|
810
899
|
//#endregion
|
|
811
900
|
//#region lib/types/client/index.js
|
|
812
|
-
/** Required services for
|
|
901
|
+
/** Required services for subagent presentation and navigation. */
|
|
813
902
|
const inject = [
|
|
814
903
|
"sessions",
|
|
904
|
+
"uiWorkspace",
|
|
815
905
|
"slots",
|
|
816
|
-
"locale"
|
|
906
|
+
"locale",
|
|
907
|
+
"sidebarRight"
|
|
817
908
|
];
|
|
818
909
|
/** Claim the composer for one-shot history or an unavailable continuation owner. */
|
|
819
910
|
function selectReadOnlySubagent(owner) {
|
|
820
911
|
const subagent = owner.session?.subagent;
|
|
821
912
|
if (subagent === void 0 || subagent === null) return null;
|
|
913
|
+
if (subagent.address.mode === "unknown") return { reason: "unknown" };
|
|
822
914
|
if (subagent.address.mode === "one-shot") return { reason: "one-shot" };
|
|
823
915
|
if (subagent.parentAvailable !== false) return null;
|
|
824
916
|
return owner.session?.running === true ? null : { reason: "parent-unavailable" };
|
|
@@ -832,16 +924,21 @@ window.__ModuleLoader__.load({
|
|
|
832
924
|
zh,
|
|
833
925
|
en
|
|
834
926
|
}), "ui-subagent: dictionaries");
|
|
835
|
-
|
|
927
|
+
ctx.inject(["resources", "sidebarRightTabs"], (scope) => {
|
|
928
|
+
registerSidebarChat(scope, ctx.locale.bind(NS));
|
|
929
|
+
});
|
|
836
930
|
const catalogActions = (_parentSessionId) => ({
|
|
837
931
|
openChild(address) {
|
|
838
|
-
|
|
932
|
+
ctx.uiWorkspace.openSession(address);
|
|
839
933
|
},
|
|
840
|
-
|
|
841
|
-
|
|
934
|
+
openChildAside(address) {
|
|
935
|
+
ctx.sidebarRight.openResource(subagentChatAddress(address), {
|
|
936
|
+
kind: "subagentchat",
|
|
937
|
+
preferNewPane: true
|
|
938
|
+
});
|
|
842
939
|
},
|
|
843
|
-
|
|
844
|
-
sessions.
|
|
940
|
+
refreshProjection(parentSessionId) {
|
|
941
|
+
ctx.sessions.refreshProjections(parentSessionId);
|
|
845
942
|
}
|
|
846
943
|
});
|
|
847
944
|
ctx.slots.inject("conversation.session.header.lineage", () => ctx.slots.register({
|
|
@@ -849,6 +946,13 @@ window.__ModuleLoader__.load({
|
|
|
849
946
|
locale: NS,
|
|
850
947
|
inject: catalogActions
|
|
851
948
|
}, SubagentHeaderLineage));
|
|
949
|
+
ctx.slots.inject("conversation.session.header.actions", () => ctx.slots.register({
|
|
950
|
+
name: "conversation.session.header.actions",
|
|
951
|
+
id: "subagent-catalog",
|
|
952
|
+
order: 30,
|
|
953
|
+
locale: NS,
|
|
954
|
+
inject: catalogActions
|
|
955
|
+
}, SubagentCatalogAction));
|
|
852
956
|
ctx.slots.inject("conversation.composer", () => ctx.slots.register({
|
|
853
957
|
name: "conversation.composer",
|
|
854
958
|
priority: -10,
|