@deepseek-ai/dsh-client-ui-subagent 0.1.6-alpha.1 → 0.1.6-alpha.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.
- package/README.i18n.yaml +2 -2
- package/README.md +3 -1
- package/README.zh.md +3 -1
- package/lib/client.js +212 -16
- package/lib/types/client/SubagentHeaderLineage.d.ts +2 -1
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/locales.d.ts +2 -0
- package/lib/types/client/sidebar-chat/index.d.ts +62 -0
- package/package.json +23 -15
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/client/ui-subagent/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: d0dadc79f552c28c5fea20a23a91c25a24e8ed61
|
|
6
|
+
README.zh.md: 295206ace11baf67112db17b5bda10a52b80d9aa
|
package/README.md
CHANGED
|
@@ -25,7 +25,9 @@ Use this package to browse every subagent conversation beneath a parent session,
|
|
|
25
25
|
<a id="use-this-package"></a>
|
|
26
26
|
## Use this package
|
|
27
27
|
|
|
28
|
-
The session header keeps the current session title as the lineage breadcrumb and, when the session has subagent descendants, appends a `/` count trigger before the header's action row; the trigger opens the descendant catalog, counts the complete subagent-only lineage, stops at ordinary forks, and shows ongoing activity when any counted descendant is running. Select any depth to open that child's conversation with its exact `{parentSessionId, childSessionId, mode}` address.
|
|
28
|
+
The session header keeps the current session title as the lineage breadcrumb and, when the session has subagent descendants, appends a `/` count trigger before the header's action row; the trigger opens the descendant catalog, counts the complete subagent-only lineage, stops at ordinary forks, and shows ongoing activity when any counted descendant is running. Select any depth to open that child's conversation with its exact `{parentSessionId, childSessionId, mode}` address, or use the row's trailing arrow to open the same address in the right Sidebar, preferring a separate pane when room permits.
|
|
29
|
+
|
|
30
|
+
This package registers the `dsh-resource://subagentchat/session/<child>?parent=<parent>&mode=<mode>` resource and builtin Sidebar tab type. The resource refreshes the direct-parent catalog before it retains the child `SessionReference`, and releases the reference when the tab record closes. The tab renders the shared `conversation.content` Factory through `sidebar.chat.conversation`, fixes the local View to Chat, and omits the main Conversation header and width controls.
|
|
29
31
|
|
|
30
32
|
### Browsing the tree
|
|
31
33
|
|
package/README.zh.md
CHANGED
|
@@ -25,7 +25,9 @@ kind: "package-reference"
|
|
|
25
25
|
<a id="use-this-package"></a>
|
|
26
26
|
## 使用本包
|
|
27
27
|
|
|
28
|
-
会话页头保留当前会话 title 作为谱系面包屑,并在会话存在 subagent 后代时,于页头操作行之前追加 `/` 数量触发器;触发器打开后代目录,统计仅含 subagent 的完整谱系、在普通 fork 处停止,并在任一计入统计的后代处于 `running` 时显示活动仍在进行。选择任意深度,即可用该子会话的确切 `{parentSessionId, childSessionId, mode}`
|
|
28
|
+
会话页头保留当前会话 title 作为谱系面包屑,并在会话存在 subagent 后代时,于页头操作行之前追加 `/` 数量触发器;触发器打开后代目录,统计仅含 subagent 的完整谱系、在普通 fork 处停止,并在任一计入统计的后代处于 `running` 时显示活动仍在进行。选择任意深度,即可用该子会话的确切 `{parentSessionId, childSessionId, mode}` 地址打开其对话;也可以使用行尾箭头在右侧 Sidebar 打开同一地址,并在空间允许时优先使用独立分栏。
|
|
29
|
+
|
|
30
|
+
本包注册 `dsh-resource://subagentchat/session/<child>?parent=<parent>&mode=<mode>` 资源与 builtin Sidebar tab 类型。资源先刷新直接 parent 目录,再保留 child 的 `SessionReference`,并在 tab 记录关闭时释放 reference。tab 通过 `sidebar.chat.conversation` 渲染共享 `conversation.content` Factory,把局部 View 固定为 Chat,并省略主 Conversation 的 Header 与宽度控制。
|
|
29
31
|
|
|
30
32
|
### 浏览目录
|
|
31
33
|
|
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_separator{color:var(--dsw-alias-label-caption);font-size:14px;line-height:20px}.ZKlsPq_activitySlot{flex:none;width:10px;height:10px;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);--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);width:336px;max-width:min(400px,100vw - 32px);max-height:min(560px,100vh - 140px);box-shadow:var(--dsw-elevation-prominent);border-radius:20px;flex-direction:column;padding:4px;display:flex;position:fixed;overflow:auto}.ZKlsPq_node{min-width:0;position:relative}.ZKlsPq_menu>.ZKlsPq_node{margin-left:-3px}.ZKlsPq_row{box-sizing:border-box;width:100%;min-height:50px;color:var(--dsw-alias-label-primary);text-align:left;cursor:pointer;background:0 0;border:0;border-radius:8px;outline:none;align-items:flex-start;gap:8px;padding:7px 8px 7px 11px;font-size:13px;line-height:18px;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:8px;flex:1;align-self:stretch;align-items:flex-start;gap:8px;min-width:0;margin:-7px -8px;padding:7px 8px;display:flex}.ZKlsPq_row>[data-state],.ZKlsPq_clickarea>[data-state]{margin-top:4px}.ZKlsPq_disabled{color:var(--dsw-alias-label-dimmed);cursor:not-allowed}.ZKlsPq_disabled:hover{background:0 0}.ZKlsPq_loadingRow{cursor:default}.ZKlsPq_disclosure,.ZKlsPq_disclosureSpace{flex:none;width:14px;height:18px}.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: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:11px;line-height:16px}.ZKlsPq_metrics{font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap;flex:none;grid-template-rows:18px 16px;display:grid}.ZKlsPq_metricToken{grid-row:1;line-height:18px}.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:18px;padding-left:4px;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:26px;top:-26px}.ZKlsPq_children[aria-busy=true]:before{content:none}.ZKlsPq_children>.ZKlsPq_node:before{top:0;bottom:0;left:-4px}.ZKlsPq_children>.ZKlsPq_node:last-child:before{height:17px;bottom:auto}.ZKlsPq_children>.ZKlsPq_node>.ZKlsPq_row:before{content:\"\";border-top:.5px solid var(--dsw-alias-border-l2);width:14px;position:absolute;top:16px;left:-4px}.ZKlsPq_notice,.ZKlsPq_error{color:var(--dsw-alias-label-tertiary);padding:10px 12px;font-size:12px;line-height:18px}.ZKlsPq_error{color:var(--dsw-alias-state-error-primary);justify-content:space-between;align-items:center;gap:12px;display:flex}.ZKlsPq_refresh{color:inherit;cursor:pointer;background:0 0;border:0;border-radius:6px;flex:none;align-items:center;gap:4px;padding:4px 6px;display:inline-flex}.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 = {
|
|
@@ -42,6 +42,7 @@ window.__ModuleLoader__.load({
|
|
|
42
42
|
"root": "ZKlsPq_root",
|
|
43
43
|
"row": "ZKlsPq_row",
|
|
44
44
|
"separator": "ZKlsPq_separator",
|
|
45
|
+
"sidebarButton": "ZKlsPq_sidebarButton",
|
|
45
46
|
"summary": "ZKlsPq_summary",
|
|
46
47
|
"switcherRoot": "ZKlsPq_switcherRoot",
|
|
47
48
|
"switcherTitle": "ZKlsPq_switcherTitle",
|
|
@@ -220,7 +221,7 @@ window.__ModuleLoader__.load({
|
|
|
220
221
|
}, summary.id));
|
|
221
222
|
}
|
|
222
223
|
/** Render one catalog level and recurse only through explicitly expanded rows. */
|
|
223
|
-
function CatalogRows({ parentSessionId, currentSessionId, catalog, catalogs, summaries, expanded, level, now, openChild, refresh, toggleBranch, closeCatalog, t }) {
|
|
224
|
+
function CatalogRows({ parentSessionId, currentSessionId, catalog, catalogs, summaries, expanded, level, now, openChild, openChildAside, refresh, toggleBranch, closeCatalog, t }) {
|
|
224
225
|
const emptyLoading = catalog.state === "loading" && catalog.entries.length === 0;
|
|
225
226
|
const reserveDisclosure = catalog.entries.some((entry) => entry.kind === "child" && entry.hasChildren);
|
|
226
227
|
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
@@ -300,6 +301,16 @@ window.__ModuleLoader__.load({
|
|
|
300
301
|
});
|
|
301
302
|
closeCatalog();
|
|
302
303
|
};
|
|
304
|
+
const openAside = (event) => {
|
|
305
|
+
event.preventDefault();
|
|
306
|
+
event.stopPropagation();
|
|
307
|
+
openChildAside({
|
|
308
|
+
parentSessionId,
|
|
309
|
+
childSessionId: entry.id,
|
|
310
|
+
mode: entry.mode
|
|
311
|
+
});
|
|
312
|
+
closeCatalog();
|
|
313
|
+
};
|
|
303
314
|
const handleKey = (event) => {
|
|
304
315
|
if (event.key === "Enter" || event.key === " ") {
|
|
305
316
|
event.preventDefault();
|
|
@@ -363,6 +374,17 @@ window.__ModuleLoader__.load({
|
|
|
363
374
|
title: t("duration.exactTitle", { duration: durationMetric.exact }),
|
|
364
375
|
children: durationMetric.compact
|
|
365
376
|
})]
|
|
377
|
+
}),
|
|
378
|
+
!isCurrent && (0, react_jsx_runtime.jsx)("button", {
|
|
379
|
+
type: "button",
|
|
380
|
+
className: SubagentHeaderLineage_module_css_default.sidebarButton,
|
|
381
|
+
"aria-label": t("open.sidebar", { label }),
|
|
382
|
+
title: t("open.sidebar", { label }),
|
|
383
|
+
onClick: openAside,
|
|
384
|
+
onKeyDown: (event) => {
|
|
385
|
+
event.stopPropagation();
|
|
386
|
+
},
|
|
387
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14, {})
|
|
366
388
|
})
|
|
367
389
|
]
|
|
368
390
|
})]
|
|
@@ -385,6 +407,7 @@ window.__ModuleLoader__.load({
|
|
|
385
407
|
level: level + 1,
|
|
386
408
|
now,
|
|
387
409
|
openChild,
|
|
410
|
+
openChildAside,
|
|
388
411
|
refresh,
|
|
389
412
|
toggleBranch,
|
|
390
413
|
closeCatalog,
|
|
@@ -406,7 +429,7 @@ window.__ModuleLoader__.load({
|
|
|
406
429
|
};
|
|
407
430
|
}
|
|
408
431
|
/** One trigger-plus-tree dropdown over the catalog rooted at `rootSessionId`. */
|
|
409
|
-
function CatalogDropdown({ rootSessionId, currentSessionId, displayTitle, openTitle, variant, separator = false, useSessions, openChild, refresh, setCatalogOpen, t }) {
|
|
432
|
+
function CatalogDropdown({ rootSessionId, currentSessionId, displayTitle, openTitle, variant, separator = false, useSessions, openChild, openChildAside, refresh, setCatalogOpen, t }) {
|
|
410
433
|
const ancestorSwitcher = variant === "switcher" && openTitle !== void 0;
|
|
411
434
|
const catalogs = useSessions((state) => state.subagentsByParent);
|
|
412
435
|
const summaries = useSessions((state) => state.byId);
|
|
@@ -648,6 +671,7 @@ window.__ModuleLoader__.load({
|
|
|
648
671
|
level: 1,
|
|
649
672
|
now,
|
|
650
673
|
openChild,
|
|
674
|
+
openChildAside,
|
|
651
675
|
refresh,
|
|
652
676
|
toggleBranch,
|
|
653
677
|
closeCatalog: () => {
|
|
@@ -664,7 +688,7 @@ window.__ModuleLoader__.load({
|
|
|
664
688
|
* @param props - Breadcrumb title, session standard props, and catalog actions.
|
|
665
689
|
* @returns An ordinary-title descendant count, or a title-and-chevron sibling switcher.
|
|
666
690
|
*/
|
|
667
|
-
function SubagentHeaderLineage({ lineageSessionId, displayTitle, openTitle, useSessions, openChild, refresh, setCatalogOpen, t }) {
|
|
691
|
+
function SubagentHeaderLineage({ lineageSessionId, displayTitle, openTitle, useSessions, openChild, openChildAside, refresh, setCatalogOpen, t }) {
|
|
668
692
|
const parentId = useSessions((state) => {
|
|
669
693
|
const summary = state.byId[lineageSessionId];
|
|
670
694
|
return summary?.origin === "subagent" ? summary.parentId : void 0;
|
|
@@ -672,6 +696,7 @@ window.__ModuleLoader__.load({
|
|
|
672
696
|
const shared = {
|
|
673
697
|
useSessions,
|
|
674
698
|
openChild,
|
|
699
|
+
openChildAside,
|
|
675
700
|
refresh,
|
|
676
701
|
setCatalogOpen,
|
|
677
702
|
t
|
|
@@ -697,13 +722,13 @@ window.__ModuleLoader__.load({
|
|
|
697
722
|
}
|
|
698
723
|
//#endregion
|
|
699
724
|
//#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) {
|
|
725
|
+
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}";
|
|
726
|
+
const tagId$1 = "@deepseek-ai/dsh-client-ui-subagent/SubagentReadOnlyComposer.module.css";
|
|
727
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
703
728
|
const tag = document.createElement("style");
|
|
704
729
|
tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-subagent";
|
|
705
|
-
tag.dataset.pluginCss = tagId;
|
|
706
|
-
tag.textContent = css;
|
|
730
|
+
tag.dataset.pluginCss = tagId$1;
|
|
731
|
+
tag.textContent = css$1;
|
|
707
732
|
document.head.appendChild(tag);
|
|
708
733
|
}
|
|
709
734
|
var SubagentReadOnlyComposer_module_css_default = { "frame": "XJ7liG_frame" };
|
|
@@ -723,6 +748,162 @@ window.__ModuleLoader__.load({
|
|
|
723
748
|
});
|
|
724
749
|
}
|
|
725
750
|
//#endregion
|
|
751
|
+
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-subagent/src/client/sidebar-chat/SidebarChat.module.css.mjs
|
|
752
|
+
const css = ".olTFqa_root{width:100%;min-width:0;height:100%;min-height:0;display:flex}";
|
|
753
|
+
const tagId = "@deepseek-ai/dsh-client-ui-subagent/SidebarChat.module.css";
|
|
754
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
755
|
+
const tag = document.createElement("style");
|
|
756
|
+
tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-subagent";
|
|
757
|
+
tag.dataset.pluginCss = tagId;
|
|
758
|
+
tag.textContent = css;
|
|
759
|
+
document.head.appendChild(tag);
|
|
760
|
+
}
|
|
761
|
+
var SidebarChat_module_css_default = { "root": "olTFqa_root" };
|
|
762
|
+
//#endregion
|
|
763
|
+
//#region lib/types/client/sidebar-chat/index.js
|
|
764
|
+
/** Stable implementation identity for the Sidebar tab body. */
|
|
765
|
+
const SUBAGENT_CHAT_ID = "@deepseek-ai/dsh-client-ui-subagent";
|
|
766
|
+
/** Resource-address prefix for an embedded Session chat. */
|
|
767
|
+
const SUBAGENT_CHAT_ADDRESS = "dsh-resource://subagentchat/session/";
|
|
768
|
+
/**
|
|
769
|
+
* Address one subagent Session together with the routing facts needed to restore it.
|
|
770
|
+
* @param address - durable direct-parent subagent address.
|
|
771
|
+
* @returns canonical Sidebar resource address.
|
|
772
|
+
*/
|
|
773
|
+
function subagentChatAddress(address) {
|
|
774
|
+
const query = new URLSearchParams({
|
|
775
|
+
parent: address.parentSessionId,
|
|
776
|
+
mode: address.mode
|
|
777
|
+
});
|
|
778
|
+
return `${SUBAGENT_CHAT_ADDRESS}${encodeURIComponent(address.childSessionId)}?${query}`;
|
|
779
|
+
}
|
|
780
|
+
/**
|
|
781
|
+
* Parse one canonical Sidebar chat resource address.
|
|
782
|
+
* @param value - possible chat resource address.
|
|
783
|
+
* @returns the encoded direct-parent address, or undefined for another or malformed resource.
|
|
784
|
+
*/
|
|
785
|
+
function parseSubagentChatAddress(value) {
|
|
786
|
+
let url;
|
|
787
|
+
try {
|
|
788
|
+
url = new URL(value);
|
|
789
|
+
} catch (_invalidUrl) {
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
792
|
+
if (url.protocol !== "dsh-resource:" || url.hostname.toLowerCase() !== "subagentchat") return void 0;
|
|
793
|
+
const parts = url.pathname.split("/").filter(Boolean);
|
|
794
|
+
if (parts.length !== 2 || parts[0] !== "session") return void 0;
|
|
795
|
+
const parentSessionId = url.searchParams.get("parent");
|
|
796
|
+
const mode = url.searchParams.get("mode");
|
|
797
|
+
if (parentSessionId === null || parentSessionId === "" || mode !== "one-shot" && mode !== "continuable") return;
|
|
798
|
+
try {
|
|
799
|
+
return {
|
|
800
|
+
parentSessionId,
|
|
801
|
+
childSessionId: decodeURIComponent(parts[1]),
|
|
802
|
+
mode
|
|
803
|
+
};
|
|
804
|
+
} catch (_invalidEncoding) {
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
function waitForAbort(signal) {
|
|
809
|
+
if (signal.aborted) return Promise.resolve();
|
|
810
|
+
return new Promise((resolve) => {
|
|
811
|
+
signal.addEventListener("abort", () => {
|
|
812
|
+
resolve();
|
|
813
|
+
}, { once: true });
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
function isAbortRequested(signal) {
|
|
817
|
+
return signal.aborted;
|
|
818
|
+
}
|
|
819
|
+
function subagentChatResourceProvider(sessions) {
|
|
820
|
+
return {
|
|
821
|
+
protocol: "subagentchat",
|
|
822
|
+
async *open(resourceAddress, { signal }) {
|
|
823
|
+
const address = parseSubagentChatAddress(resourceAddress);
|
|
824
|
+
if (address === void 0) throw new Error(`ui-subagent: invalid chat resource address "${resourceAddress}"`);
|
|
825
|
+
if (isAbortRequested(signal)) return;
|
|
826
|
+
await sessions.refreshSubagents(address.parentSessionId);
|
|
827
|
+
if (isAbortRequested(signal)) return;
|
|
828
|
+
const reference = sessions.retain(address, {
|
|
829
|
+
source: "sidebarChat",
|
|
830
|
+
signal
|
|
831
|
+
});
|
|
832
|
+
try {
|
|
833
|
+
yield {
|
|
834
|
+
ok: true,
|
|
835
|
+
value: {
|
|
836
|
+
address,
|
|
837
|
+
reference
|
|
838
|
+
}
|
|
839
|
+
};
|
|
840
|
+
await waitForAbort(signal);
|
|
841
|
+
} finally {
|
|
842
|
+
reference.release();
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
/** Fixed Chat selection used by an embedded Conversation occurrence. */
|
|
848
|
+
function FixedChatConversationView(props) {
|
|
849
|
+
return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: props.renderSlot("conversation.session", { view: "chat" }) });
|
|
850
|
+
}
|
|
851
|
+
/** Render the shared Conversation content for one explicitly provided child Session. */
|
|
852
|
+
function ConversationSlotPanel({ sessionId, useSession, useConversation, useSessions, renderFactorySlot }) {
|
|
853
|
+
const session = useSession((value) => value);
|
|
854
|
+
const shellPhase = useConversation((value) => value).activeTargets.size > 0 || !session.blank && !session.awaitingFirstTurn || session.running ? "active" : session.promptAttempted ? "engaging" : "blank";
|
|
855
|
+
const summaryBlank = useSessions((state) => state.byId[sessionId]?.blank);
|
|
856
|
+
const parentAvailabilityPending = session.subagent?.address.mode === "continuable" && session.subagent.parentAvailable === void 0;
|
|
857
|
+
const settling = shellPhase === "blank" && session.openState === "loading" && summaryBlank !== true || parentAvailabilityPending;
|
|
858
|
+
const hero = shellPhase === "blank" && (session.openState === "open" || summaryBlank === true);
|
|
859
|
+
return renderFactorySlot("conversation.content", {
|
|
860
|
+
variant: "embedded",
|
|
861
|
+
phase: settling ? "settling" : hero ? "hero" : "active",
|
|
862
|
+
hero
|
|
863
|
+
}, { slots: { views: FixedChatConversationView } });
|
|
864
|
+
}
|
|
865
|
+
/** Bind a chat resource's child reference around its Conversation slot. */
|
|
866
|
+
function SidebarChatTab({ useResource, useTabInfo, SessionProvider, renderSlot }) {
|
|
867
|
+
const { tab } = useTabInfo();
|
|
868
|
+
const resource = useResource(tab.contentId);
|
|
869
|
+
return (0, react_jsx_runtime.jsx)("div", {
|
|
870
|
+
className: SidebarChat_module_css_default.root,
|
|
871
|
+
"data-sidebar-chat": "",
|
|
872
|
+
children: resource.value === void 0 ? null : (0, react_jsx_runtime.jsx)(SessionProvider, {
|
|
873
|
+
session: resource.value.reference,
|
|
874
|
+
children: renderSlot("sidebar.chat.conversation", {})
|
|
875
|
+
})
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* Register the chat resource owner and its right-Sidebar presentation.
|
|
880
|
+
* @param ctx - Client root carrying Sessions, resources, Slots, and Sidebar registries.
|
|
881
|
+
* @param t - Chat namespace translator used for fallback tab titles.
|
|
882
|
+
*/
|
|
883
|
+
function registerSidebarChat(ctx, t) {
|
|
884
|
+
ctx.effect(() => ctx.resources.register(subagentChatResourceProvider(ctx.sessions)), "ui-subagent: Sidebar chat resources");
|
|
885
|
+
ctx.effect(() => ctx.sidebarRightTabs.register({
|
|
886
|
+
id: SUBAGENT_CHAT_ID,
|
|
887
|
+
kind: "subagentchat",
|
|
888
|
+
patterns: [`${SUBAGENT_CHAT_ADDRESS}**`],
|
|
889
|
+
priority: "builtin",
|
|
890
|
+
canOpen: (address) => parseSubagentChatAddress(address) !== void 0,
|
|
891
|
+
title: (address) => {
|
|
892
|
+
const child = parseSubagentChatAddress(address)?.childSessionId;
|
|
893
|
+
return child === void 0 ? t("sidebar.chat") : ctx.sessions.list.getSnapshot().byId[child]?.projectionValues?.subagent?.label ?? child;
|
|
894
|
+
}
|
|
895
|
+
}), "ui-subagent: Sidebar chat type");
|
|
896
|
+
ctx.effect(() => ctx.slots.inject("sidebar.right.pane.tab", () => ctx.slots.register({
|
|
897
|
+
name: "sidebar.right.pane.tab",
|
|
898
|
+
key: SUBAGENT_CHAT_ID,
|
|
899
|
+
children: { "sidebar.chat.conversation": {
|
|
900
|
+
kind: "single",
|
|
901
|
+
scope: "session"
|
|
902
|
+
} }
|
|
903
|
+
}, SidebarChatTab)), "ui-subagent: Sidebar chat body");
|
|
904
|
+
ctx.effect(() => ctx.slots.inject("sidebar.chat.conversation", () => ctx.slots.register({ name: "sidebar.chat.conversation" }, ConversationSlotPanel)), "ui-subagent: Sidebar Conversation");
|
|
905
|
+
}
|
|
906
|
+
//#endregion
|
|
726
907
|
//#region lib/types/client/locales.js
|
|
727
908
|
/** `subagent` namespace dictionaries. */
|
|
728
909
|
/** Dictionary namespace owned by this plugin. */
|
|
@@ -762,6 +943,8 @@ window.__ModuleLoader__.load({
|
|
|
762
943
|
"count.running.other": "{count} 个子代理,正在运行",
|
|
763
944
|
"switcher.aria": "切换子代理:{title}",
|
|
764
945
|
"tree.aria": "子代理会话",
|
|
946
|
+
"open.sidebar": "在侧边栏打开 {label}",
|
|
947
|
+
"sidebar.chat": "聊天",
|
|
765
948
|
"readonly.oneShot.title": "一次性子代理记录",
|
|
766
949
|
"readonly.title": "此子代理暂时只读",
|
|
767
950
|
"readonly.oneShot.body": "一次性任务不支持后续消息,可在这里查看完整执行记录。",
|
|
@@ -802,6 +985,8 @@ window.__ModuleLoader__.load({
|
|
|
802
985
|
"count.running.other": "{count} subagents running",
|
|
803
986
|
"switcher.aria": "Switch subagent: {title}",
|
|
804
987
|
"tree.aria": "Subagent sessions",
|
|
988
|
+
"open.sidebar": "Open {label} in sidebar",
|
|
989
|
+
"sidebar.chat": "Chat",
|
|
805
990
|
"readonly.oneShot.title": "One-shot subagent record",
|
|
806
991
|
"readonly.title": "This subagent is read-only for now",
|
|
807
992
|
"readonly.oneShot.body": "One-shot tasks do not accept follow-ups; review the full execution record here.",
|
|
@@ -809,11 +994,13 @@ window.__ModuleLoader__.load({
|
|
|
809
994
|
};
|
|
810
995
|
//#endregion
|
|
811
996
|
//#region lib/types/client/index.js
|
|
812
|
-
/** Required services for
|
|
997
|
+
/** Required services for subagent presentation and navigation. */
|
|
813
998
|
const inject = [
|
|
814
999
|
"sessions",
|
|
1000
|
+
"uiWorkspace",
|
|
815
1001
|
"slots",
|
|
816
|
-
"locale"
|
|
1002
|
+
"locale",
|
|
1003
|
+
"sidebarRight"
|
|
817
1004
|
];
|
|
818
1005
|
/** Claim the composer for one-shot history or an unavailable continuation owner. */
|
|
819
1006
|
function selectReadOnlySubagent(owner) {
|
|
@@ -832,10 +1019,19 @@ window.__ModuleLoader__.load({
|
|
|
832
1019
|
zh,
|
|
833
1020
|
en
|
|
834
1021
|
}), "ui-subagent: dictionaries");
|
|
1022
|
+
ctx.inject(["resources", "sidebarRightTabs"], (scope) => {
|
|
1023
|
+
registerSidebarChat(scope, ctx.locale.bind(NS));
|
|
1024
|
+
});
|
|
835
1025
|
const sessions = ctx.sessions;
|
|
836
1026
|
const catalogActions = (_parentSessionId) => ({
|
|
837
1027
|
openChild(address) {
|
|
838
|
-
|
|
1028
|
+
ctx.uiWorkspace.openSession(address);
|
|
1029
|
+
},
|
|
1030
|
+
openChildAside(address) {
|
|
1031
|
+
ctx.sidebarRight.openResource(subagentChatAddress(address), {
|
|
1032
|
+
kind: "subagentchat",
|
|
1033
|
+
preferNewPane: true
|
|
1034
|
+
});
|
|
839
1035
|
},
|
|
840
1036
|
refresh(parentSessionId) {
|
|
841
1037
|
sessions.refreshSubagents(parentSessionId);
|
|
@@ -5,6 +5,7 @@ import { NS } from './locales.ts';
|
|
|
5
5
|
/** Business actions supplied by the slot registration. */
|
|
6
6
|
export interface SubagentCatalogInjected {
|
|
7
7
|
openChild: (address: SubagentAddress) => void;
|
|
8
|
+
openChildAside: (address: SubagentAddress) => void;
|
|
8
9
|
refresh: (parentSessionId: SessionId) => void;
|
|
9
10
|
setCatalogOpen: (parentSessionId: SessionId, open: boolean) => void;
|
|
10
11
|
}
|
|
@@ -15,5 +16,5 @@ export type SubagentHeaderLineageProps = PropsRuntime<'conversation.session.head
|
|
|
15
16
|
* @param props - Breadcrumb title, session standard props, and catalog actions.
|
|
16
17
|
* @returns An ordinary-title descendant count, or a title-and-chevron sibling switcher.
|
|
17
18
|
*/
|
|
18
|
-
export declare function SubagentHeaderLineage({ lineageSessionId, displayTitle, openTitle, useSessions, openChild, refresh, setCatalogOpen, t, }: SubagentHeaderLineageProps): import("react").JSX.Element;
|
|
19
|
+
export declare function SubagentHeaderLineage({ lineageSessionId, displayTitle, openTitle, useSessions, openChild, openChildAside, refresh, setCatalogOpen, t, }: SubagentHeaderLineageProps): import("react").JSX.Element;
|
|
19
20
|
//# sourceMappingURL=SubagentHeaderLineage.d.ts.map
|
|
@@ -9,7 +9,7 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
|
9
9
|
}
|
|
10
10
|
export type { SubagentCatalogInjected, SubagentHeaderLineageProps, } from './SubagentHeaderLineage.tsx';
|
|
11
11
|
export type { SubagentReadOnlyComposerProps, SubagentReadOnlyMatch, } from './SubagentReadOnlyComposer.tsx';
|
|
12
|
-
/** Required services for
|
|
12
|
+
/** Required services for subagent presentation and navigation. */
|
|
13
13
|
export declare const inject: string[];
|
|
14
14
|
/**
|
|
15
15
|
* Client plugin body: register the subagent catalog and read-only composer seats.
|
|
@@ -36,6 +36,8 @@ export declare const zh: {
|
|
|
36
36
|
readonly 'count.running.other': "{count} 个子代理,正在运行";
|
|
37
37
|
readonly 'switcher.aria': "切换子代理:{title}";
|
|
38
38
|
readonly 'tree.aria': "子代理会话";
|
|
39
|
+
readonly 'open.sidebar': "在侧边栏打开 {label}";
|
|
40
|
+
readonly 'sidebar.chat': "聊天";
|
|
39
41
|
readonly 'readonly.oneShot.title': "一次性子代理记录";
|
|
40
42
|
readonly 'readonly.title': "此子代理暂时只读";
|
|
41
43
|
readonly 'readonly.oneShot.body': "一次性任务不支持后续消息,可在这里查看完整执行记录。";
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/** Right-Sidebar presentation of an existing subagent Conversation. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import type { SessionReference } from '@deepseek-ai/dsh-api-session-controller/client';
|
|
4
|
+
import type { ConversationViewsProps } from '@deepseek-ai/dsh-client-ui-conversation/client';
|
|
5
|
+
import type { PropsRenderFactories, PropsRenderSlots, PropsRuntime, TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
|
|
6
|
+
import type { SubagentAddress } from '@deepseek-ai/dsh-subagent/client';
|
|
7
|
+
import type { NS } from '../locales.ts';
|
|
8
|
+
/** Stable implementation identity for the Sidebar tab body. */
|
|
9
|
+
export declare const SUBAGENT_CHAT_ID = "@deepseek-ai/dsh-client-ui-subagent";
|
|
10
|
+
/** Resource-address prefix for an embedded Session chat. */
|
|
11
|
+
export declare const SUBAGENT_CHAT_ADDRESS = "dsh-resource://subagentchat/session/";
|
|
12
|
+
/** Value retained by one live chat resource occurrence. */
|
|
13
|
+
export interface SubagentChatResource {
|
|
14
|
+
readonly address: SubagentAddress;
|
|
15
|
+
readonly reference: SessionReference;
|
|
16
|
+
}
|
|
17
|
+
declare module '@deepseek-ai/dsh-api-session-controller/client' {
|
|
18
|
+
interface SessionReferenceSourceMap {
|
|
19
|
+
sidebarChat: unknown;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
23
|
+
interface ResourceProtocolMap {
|
|
24
|
+
subagentchat: SubagentChatResource;
|
|
25
|
+
}
|
|
26
|
+
interface SlotMap {
|
|
27
|
+
/** Session-scoped Conversation occurrence hosted by one Sidebar chat tab. */
|
|
28
|
+
'sidebar.chat.conversation': {
|
|
29
|
+
kind: 'single';
|
|
30
|
+
scope: 'session';
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Address one subagent Session together with the routing facts needed to restore it.
|
|
36
|
+
* @param address - durable direct-parent subagent address.
|
|
37
|
+
* @returns canonical Sidebar resource address.
|
|
38
|
+
*/
|
|
39
|
+
export declare function subagentChatAddress(address: SubagentAddress): string;
|
|
40
|
+
/**
|
|
41
|
+
* Parse one canonical Sidebar chat resource address.
|
|
42
|
+
* @param value - possible chat resource address.
|
|
43
|
+
* @returns the encoded direct-parent address, or undefined for another or malformed resource.
|
|
44
|
+
*/
|
|
45
|
+
export declare function parseSubagentChatAddress(value: string): SubagentAddress | undefined;
|
|
46
|
+
/** Fixed Chat selection used by an embedded Conversation occurrence. */
|
|
47
|
+
export declare function FixedChatConversationView(props: ConversationViewsProps): import("react").JSX.Element;
|
|
48
|
+
/** Props supplied to the child-Session Conversation host. */
|
|
49
|
+
export type ConversationSlotPanelProps = PropsRuntime<'sidebar.chat.conversation'> & PropsRenderFactories;
|
|
50
|
+
/** Render the shared Conversation content for one explicitly provided child Session. */
|
|
51
|
+
export declare function ConversationSlotPanel({ sessionId, useSession, useConversation, useSessions, renderFactorySlot, }: ConversationSlotPanelProps): import("react").ReactNode;
|
|
52
|
+
/** Props supplied to the parent-Session Sidebar tab body. */
|
|
53
|
+
export type SidebarChatTabProps = PropsRuntime<'sidebar.right.pane.tab'> & PropsRenderSlots<'sidebar.chat.conversation'>;
|
|
54
|
+
/** Bind a chat resource's child reference around its Conversation slot. */
|
|
55
|
+
export declare function SidebarChatTab({ useResource, useTabInfo, SessionProvider, renderSlot }: SidebarChatTabProps): import("react").JSX.Element;
|
|
56
|
+
/**
|
|
57
|
+
* Register the chat resource owner and its right-Sidebar presentation.
|
|
58
|
+
* @param ctx - Client root carrying Sessions, resources, Slots, and Sidebar registries.
|
|
59
|
+
* @param t - Chat namespace translator used for fallback tab titles.
|
|
60
|
+
*/
|
|
61
|
+
export declare function registerSidebarChat(ctx: Context, t: TranslateNS<typeof NS>): void;
|
|
62
|
+
//# sourceMappingURL=index.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-ui-subagent",
|
|
3
3
|
"description": "Subagent conversation catalog, continuation routing UI, and '@' reference source",
|
|
4
|
-
"version": "0.1.6-alpha.
|
|
4
|
+
"version": "0.1.6-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -30,9 +30,13 @@
|
|
|
30
30
|
"inject": [
|
|
31
31
|
"@deepseek-ai/dsh-api-session-controller",
|
|
32
32
|
"@deepseek-ai/dsh-client-locale",
|
|
33
|
+
"@deepseek-ai/dsh-client-resources",
|
|
34
|
+
"@deepseek-ai/dsh-client-ui-chat",
|
|
33
35
|
"@deepseek-ai/dsh-client-ui-conversation",
|
|
34
36
|
"@deepseek-ai/dsh-client-ui-primitives",
|
|
35
|
-
"@deepseek-ai/dsh-client-ui-
|
|
37
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right",
|
|
38
|
+
"@deepseek-ai/dsh-client-ui-input-trigger",
|
|
39
|
+
"@deepseek-ai/dsh-client-ui-workspace"
|
|
36
40
|
],
|
|
37
41
|
"platform": "web"
|
|
38
42
|
}
|
|
@@ -46,20 +50,24 @@
|
|
|
46
50
|
"@types/react-dom": "~18.3.0",
|
|
47
51
|
"react": "^18.2.0",
|
|
48
52
|
"react-dom": "^18.2.0",
|
|
49
|
-
"@deepseek-ai/dsh-client-
|
|
50
|
-
"@deepseek-ai/dsh-client-
|
|
51
|
-
"@deepseek-ai/dsh-client-locale": "^0.1.6-alpha.
|
|
52
|
-
"@deepseek-ai/dsh-client-ui-
|
|
53
|
-
"@deepseek-ai/dsh-client-ui-
|
|
54
|
-
"@deepseek-ai/dsh-client-ui-
|
|
55
|
-
"@deepseek-ai/dsh-
|
|
56
|
-
"@deepseek-ai/dsh-
|
|
53
|
+
"@deepseek-ai/dsh-client-resources": "^0.1.6-alpha.2",
|
|
54
|
+
"@deepseek-ai/dsh-client-test-runtime": "^0.1.6-alpha.2",
|
|
55
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.6-alpha.2",
|
|
56
|
+
"@deepseek-ai/dsh-client-ui-chat": "^0.1.6-alpha.2",
|
|
57
|
+
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.6-alpha.2",
|
|
58
|
+
"@deepseek-ai/dsh-client-ui-input-trigger": "^0.1.6-alpha.2",
|
|
59
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.6-alpha.2",
|
|
60
|
+
"@deepseek-ai/dsh-subagent": "^0.1.6-alpha.2",
|
|
61
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.6-alpha.2",
|
|
62
|
+
"@deepseek-ai/dsh-token-meter": "^0.1.6-alpha.2",
|
|
57
63
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
58
|
-
"@deepseek-ai/dsh-
|
|
59
|
-
"@deepseek-ai/dsh-
|
|
60
|
-
"@deepseek-ai/dsh-
|
|
61
|
-
"@deepseek-ai/dsh-client-ui-
|
|
62
|
-
"@deepseek-ai/dsh-client-ui-session": "^0.1.6-alpha.
|
|
64
|
+
"@deepseek-ai/dsh-client-connection": "^0.1.6-alpha.2",
|
|
65
|
+
"@deepseek-ai/dsh-session": "^0.1.6-alpha.2",
|
|
66
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.6-alpha.2",
|
|
67
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right": "^0.1.6-alpha.2",
|
|
68
|
+
"@deepseek-ai/dsh-client-ui-session": "^0.1.6-alpha.2",
|
|
69
|
+
"@deepseek-ai/dsh-client-ui-workspace": "^0.1.6-alpha.2",
|
|
70
|
+
"@deepseek-ai/dsh-api-session-controller": "^0.1.6-alpha.2"
|
|
63
71
|
},
|
|
64
72
|
"files": [
|
|
65
73
|
"lib/index.js",
|