@deepseek-ai/dsh-client-ui-subagent 0.1.6-alpha.2 → 0.1.7-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 +13 -7
- package/README.zh.md +13 -7
- package/lib/client.js +168 -260
- package/lib/types/client/SubagentHeaderLineage.d.ts +14 -4
- package/lib/types/client/SubagentReadOnlyComposer.d.ts +1 -1
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/locales.d.ts +3 -4
- package/package.json +20 -20
- package/lib/types/client/subagent-lineage.d.ts +0 -21
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: b3dfb4a3aa56dbf240f4b76db410d45cc6ae5651
|
|
6
|
+
README.zh.md: a6ebd6da3c3caba2a3bd015da450b5a33ab79d67
|
package/README.md
CHANGED
|
@@ -25,13 +25,13 @@ 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
|
|
28
|
+
The session header keeps the current session title as the lineage breadcrumb; when the session's direct catalog has entries or a read has failed, the descendant-count trigger renders in the header actions band after the task list, with no breadcrumb separator. An absent catalog, an empty loading catalog, or a successfully loaded empty catalog hides the count trigger. The trigger opens that direct catalog, reports its total and running counts, and loads nested catalogs only when their rows expand. 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
29
|
|
|
30
|
-
This package registers the `dsh-resource://subagentchat/session/<child>?parent=<parent>&mode=<mode>` resource and builtin Sidebar tab type. The resource
|
|
30
|
+
This package registers the `dsh-resource://subagentchat/session/<child>?parent=<parent>&mode=<mode>` resource and builtin Sidebar tab type. The resource retains the child `SessionReference` directly from its address without refreshing the parent catalog, 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.
|
|
31
31
|
|
|
32
32
|
### Browsing the tree
|
|
33
33
|
|
|
34
|
-
Rows display mode plus
|
|
34
|
+
Rows display mode plus activity and an optional log-backed title; running uses the shared ongoing loader, an inactive child whose latest closed turn completed normally uses the shared success dot, and other inactive children use the shared idle dot. Every row reserves the same 14px status column, centering smaller dots so titles align with the loader state. The compact header trigger vertically centers its activity glyph and count with a 4px gap. The trailing column stacks total durable provider usage above active-turn duration. Keyboard navigation works with ArrowRight/ArrowLeft to expand and collapse branches and ArrowUp/ArrowDown, Home, End, and Escape to navigate or close the tree. An unlabeled one-shot row falls back to its session id. A row is a known leaf only after its own catalog loads empty.
|
|
35
35
|
|
|
36
36
|
### Continuing a conversation
|
|
37
37
|
|
|
@@ -53,16 +53,22 @@ The catalog and composer behavior are specified by the [Web subagent conversatio
|
|
|
53
53
|
|
|
54
54
|
### Catalog derivation
|
|
55
55
|
|
|
56
|
-
The header lineage renderer reads `
|
|
56
|
+
The header lineage renderer reads `projectionsBySession` through the standard `useSessions` hook. The renderer selects `subagentCatalog` from each Session’s shared values for membership, disclosure, and counts; Activity prefers the unified UI status and falls back to Session summaries; summaries supply titles and usage. Expanding a row loads its initial catalog when needed. Live projection frames update every loaded level without menu subscriptions or repeated membership queries. A row remains expandable while its catalog is absent, loading, or failed, and becomes a known leaf after a ready empty catalog.
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
Opening a catalog dropdown does not request its root catalog. Child-catalog expansion and failed-read retries call `refreshProjection`; shared projection-value changes update the display automatically.
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
Breadcrumb addresses derive from the Provider-bound Session address and loaded parent catalogs, including never-selected ancestors.
|
|
61
|
+
|
|
62
|
+
### Duration, completion, and tokens
|
|
63
|
+
|
|
64
|
+
Each visible catalog level advances its own clock while it contains a running child; collapsing the level or closing the menu releases that clock. Token totals sum the four disjoint `tokenUsage` buckets. The `subagentTiming` projection sums completed-turn duration and records whether the latest closed turn ended with `completed`; opening another turn clears that completion until its own `turn/end`. Duration advances once per second only for an open turn on a running child and freezes after the child becomes inactive; an interrupted open turn is bounded by its same-cut `active.through`, never by newer session metadata.
|
|
61
65
|
|
|
62
66
|
### Composer election
|
|
63
67
|
|
|
64
68
|
One-shot children always elect a read-only composer. A continuable child elects one only when its exact parent is unavailable and the child is not running; otherwise the ordinary composer's Session routes prompts through `subagents/prompt`. This package never receives host context or calls a model-facing tool.
|
|
65
69
|
|
|
70
|
+
Unknown-mode catalog rows remain visible and clickable, using the child id when no label is available. Their composer is read-only until child history establishes a supported mode; a read failure is reported in the child conversation.
|
|
71
|
+
|
|
66
72
|
</details>
|
|
67
73
|
|
|
68
74
|
-----
|
|
@@ -104,7 +110,7 @@ Append-only. This package never edits earlier request tokens.
|
|
|
104
110
|
|
|
105
111
|
These limits define what the catalog can show and what `@` references mean; they are current package constraints.
|
|
106
112
|
|
|
107
|
-
- **
|
|
113
|
+
- **Non-completed inactive outcomes remain grouped** — the catalog distinguishes a latest normal completion from other inactive states, but does not distinguish failure, cancellation, refusal, token exhaustion, or a child with no closed turn; the UI exposes no Activation identity, and stopping is limited to the composer's current-turn Stop for a running continuable child.
|
|
108
114
|
- **`@` references remain display-title text** — duplicate or renamed labels are ambiguous, so they intentionally do not acquire continuation semantics.
|
|
109
115
|
|
|
110
116
|
<a id="dev-note"></a>
|
package/README.zh.md
CHANGED
|
@@ -25,13 +25,13 @@ kind: "package-reference"
|
|
|
25
25
|
<a id="use-this-package"></a>
|
|
26
26
|
## 使用本包
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
会话页头把当前会话标题作为谱系面包屑;当会话的直接目录有子项或读取失败时,后代数量触发器渲染在页头操作区、任务列表之后,不带任何面包屑分隔符。目录缺席、空目录加载中或成功加载为空时,均隐藏数量触发器。触发器打开该直接目录,报告总数与运行数,并且只在行展开时加载嵌套目录。选择任意深度,即可用该子会话的确切 `{parentSessionId, childSessionId, mode}` 地址打开其对话;也可以使用行尾箭头在右侧 Sidebar 打开同一地址,并在空间允许时优先使用独立分栏。
|
|
29
29
|
|
|
30
|
-
本包注册 `dsh-resource://subagentchat/session/<child>?parent=<parent>&mode=<mode>` 资源与 builtin Sidebar tab
|
|
30
|
+
本包注册 `dsh-resource://subagentchat/session/<child>?parent=<parent>&mode=<mode>` 资源与 builtin Sidebar tab 类型。资源直接根据地址保留 child 的 `SessionReference`,不刷新 parent 目录,并在 tab 记录关闭时释放 reference。tab 通过 `sidebar.chat.conversation` 渲染共享 `conversation.content` Factory,把局部 View 固定为 Chat,并省略主 Conversation 的 Header 与宽度控制。
|
|
31
31
|
|
|
32
32
|
### 浏览目录
|
|
33
33
|
|
|
34
|
-
行显示 mode
|
|
34
|
+
行显示 mode、活动状态与由日志支撑的可选 title;running 使用共享 ongoing loading,最近一个已结束轮次正常完成的 inactive child 使用共享 success 绿点,其他 inactive child 使用共享 idle 灰点。每行都为状态图标预留相同的 14px 列宽,并将较小的圆点居中,使 title 与 loading 状态对齐。紧凑的页头触发器会垂直居中活动图标与数量,并保留 4px 水平间距。尾随列在上行显示提供方的持久化 token 用量总计,在下行显示活跃轮次耗时。键盘导航:ArrowRight/ArrowLeft 展开和折叠分支;ArrowUp/ArrowDown、Home、End 与 Escape 用于导航或关闭树。没有 label 的 one-shot 行回退到其会话 id。只有一行自身的目录加载为空后,它才是已知叶子。
|
|
35
35
|
|
|
36
36
|
### 续接对话
|
|
37
37
|
|
|
@@ -53,16 +53,22 @@ kind: "package-reference"
|
|
|
53
53
|
|
|
54
54
|
### 目录派生
|
|
55
55
|
|
|
56
|
-
页头谱系 renderer 通过标准 `useSessions` 钩子读取 `
|
|
56
|
+
页头谱系 renderer 通过标准 `useSessions` 钩子读取 `projectionsBySession`。renderer 从每个 Session 的共享值中选择 `subagentCatalog`,用于成员关系、展开控件与数量;活动状态优先使用统一 UI status,缺少时使用 Session 摘要;摘要提供标题与用量。展开行会按需加载初始目录。实时 projection 帧更新所有已加载层级,无需菜单订阅或重复成员查询。行在目录缺席、加载中或失败时保持可展开,并在目录就绪且为空后成为已知叶子。
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
打开目录下拉菜单不会请求其根目录。展开子节点目录或重试失败读取时调用 `refreshProjection`;共享投影值的变化会自动更新显示。
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
面包屑地址从 Provider 所绑定的 Session 地址和已加载的 parent 目录推导,也包括从未选中过的祖先。
|
|
61
|
+
|
|
62
|
+
### 耗时、完成状态与 token
|
|
63
|
+
|
|
64
|
+
每个可见目录层在包含运行中 child 时独立推进时钟;折叠该层或关闭菜单会释放时钟。token 用量总计为四个互不重叠的 `tokenUsage` 桶之和。`subagentTiming` 投影会累加已结束轮次的耗时,并记录最近一个已结束轮次是否以 `completed` 结束;新轮次开始时会清除该完成状态,直到自身的 `turn/end` 到达。耗时仅在运行中 child 存在未结束轮次时每秒递增一次,并在 child 变为 inactive 后冻结;被中断的未结束轮次以其同一切面的 `active.through` 为上界,绝不使用更新的会话元数据。
|
|
61
65
|
|
|
62
66
|
### 编辑器选举
|
|
63
67
|
|
|
64
68
|
one-shot child 始终选用只读编辑器。可继续 child 仅在其确切 parent 不可用且 child 未在运行时选用只读编辑器;否则普通编辑器的会话会经 `subagents/prompt` 路由提示词。本包绝不接收宿主上下文,也不调用面向模型的工具。
|
|
65
69
|
|
|
70
|
+
模式未知的目录项仍可见、可点击,没有标签时显示子会话 id。读取子历史并确认受支持模式前,输入区保持只读;读取失败在该子会话中报告。
|
|
71
|
+
|
|
66
72
|
</details>
|
|
67
73
|
|
|
68
74
|
-----
|
|
@@ -104,7 +110,7 @@ one-shot child 始终选用只读编辑器。可继续 child 仅在其确切 par
|
|
|
104
110
|
|
|
105
111
|
这些限制定义目录能显示什么、`@` 引用意味着什么;它们是当前包约束。
|
|
106
112
|
|
|
107
|
-
-
|
|
113
|
+
- **非完成的 inactive 结果仍合并显示**:目录能区分最近一次正常完成与其他 inactive 状态,但不区分失败、取消、拒绝、token 耗尽或尚无已结束轮次的 child;UI 不公开 Activation 身份,停止能力仅限编辑器上针对运行中可继续 child 的当前轮次 Stop。
|
|
108
114
|
- **`@` 引用仍是显示标题文本**:重复或改名后的 label 会有歧义,因此它们刻意不获得继续执行语义。
|
|
109
115
|
|
|
110
116
|
<a id="dev-note"></a>
|
package/lib/client.js
CHANGED
|
@@ -9,7 +9,7 @@ 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$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}.
|
|
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
13
|
const tagId$2 = "@deepseek-ai/dsh-client-ui-subagent/SubagentHeaderLineage.module.css";
|
|
14
14
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
|
|
15
15
|
const tag = document.createElement("style");
|
|
@@ -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,7 @@ window.__ModuleLoader__.load({
|
|
|
41
39
|
"refresh": "ZKlsPq_refresh",
|
|
42
40
|
"root": "ZKlsPq_root",
|
|
43
41
|
"row": "ZKlsPq_row",
|
|
44
|
-
"
|
|
42
|
+
"rowActivitySlot": "ZKlsPq_rowActivitySlot",
|
|
45
43
|
"sidebarButton": "ZKlsPq_sidebarButton",
|
|
46
44
|
"summary": "ZKlsPq_summary",
|
|
47
45
|
"switcherRoot": "ZKlsPq_switcherRoot",
|
|
@@ -51,44 +49,7 @@ window.__ModuleLoader__.load({
|
|
|
51
49
|
"triggerOpen": "ZKlsPq_triggerOpen"
|
|
52
50
|
};
|
|
53
51
|
//#endregion
|
|
54
|
-
//#region lib/types/client/subagent-lineage.js
|
|
55
|
-
/** UI Subagent-owned projection of descendant counts from Session summaries. */
|
|
56
|
-
/**
|
|
57
|
-
* Index uninterrupted subagent descendants under each ancestor.
|
|
58
|
-
* @param summaries - Session summaries keyed by id.
|
|
59
|
-
* @returns descendant totals keyed by possible parent id.
|
|
60
|
-
*/
|
|
61
|
-
function indexSubagentDescendants(summaries) {
|
|
62
|
-
const indexed = /* @__PURE__ */ new Map();
|
|
63
|
-
for (const descendant of Object.values(summaries)) {
|
|
64
|
-
if (descendant.origin !== "subagent") continue;
|
|
65
|
-
const seen = /* @__PURE__ */ new Set();
|
|
66
|
-
let current = descendant;
|
|
67
|
-
while (current?.origin === "subagent" && current.parentId !== void 0 && !seen.has(current.id)) {
|
|
68
|
-
seen.add(current.id);
|
|
69
|
-
const aggregate = indexed.get(current.parentId);
|
|
70
|
-
if (aggregate === void 0) indexed.set(current.parentId, {
|
|
71
|
-
count: 1,
|
|
72
|
-
runningCount: descendant.running ? 1 : 0
|
|
73
|
-
});
|
|
74
|
-
else {
|
|
75
|
-
aggregate.count += 1;
|
|
76
|
-
if (descendant.running) aggregate.runningCount += 1;
|
|
77
|
-
}
|
|
78
|
-
current = summaries[current.parentId];
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return indexed;
|
|
82
|
-
}
|
|
83
|
-
//#endregion
|
|
84
52
|
//#region lib/types/client/SubagentHeaderLineage.js
|
|
85
|
-
function diagnosticReason(entry, t) {
|
|
86
|
-
switch (entry.reason) {
|
|
87
|
-
case "corrupt": return t("diagnostic.corrupt");
|
|
88
|
-
case "unsupported": return t("diagnostic.unsupported");
|
|
89
|
-
case "unavailable": return t("diagnostic.unavailable");
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
53
|
function treeItems(root) {
|
|
93
54
|
return root === null ? [] : Array.from(root.querySelectorAll("[role=\"treeitem\"]:not([aria-disabled=\"true\"])"));
|
|
94
55
|
}
|
|
@@ -169,10 +130,6 @@ window.__ModuleLoader__.load({
|
|
|
169
130
|
seconds: String(seconds).padStart(2, "0")
|
|
170
131
|
});
|
|
171
132
|
}
|
|
172
|
-
const NO_DESCENDANTS = {
|
|
173
|
-
count: 0,
|
|
174
|
-
runningCount: 0
|
|
175
|
-
};
|
|
176
133
|
function SubagentSwitcherIcon() {
|
|
177
134
|
return (0, react_jsx_runtime.jsxs)("svg", {
|
|
178
135
|
width: "16",
|
|
@@ -191,95 +148,56 @@ window.__ModuleLoader__.load({
|
|
|
191
148
|
})]
|
|
192
149
|
});
|
|
193
150
|
}
|
|
194
|
-
/** Render
|
|
195
|
-
function CatalogLoadingRows({
|
|
196
|
-
|
|
197
|
-
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", {
|
|
198
154
|
className: SubagentHeaderLineage_module_css_default.notice,
|
|
199
155
|
children: t("loading.label")
|
|
200
156
|
});
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
"aria-disabled": "true",
|
|
206
|
-
"aria-level": level,
|
|
207
|
-
"aria-label": t("loading.aria"),
|
|
208
|
-
className: `${SubagentHeaderLineage_module_css_default.row} ${SubagentHeaderLineage_module_css_default.disabled} ${SubagentHeaderLineage_module_css_default.loadingRow}`,
|
|
209
|
-
children: [
|
|
210
|
-
(0, react_jsx_runtime.jsx)("span", { className: SubagentHeaderLineage_module_css_default.disclosureSpace }),
|
|
211
|
-
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: summary.running ? "ongoing" : "done" }),
|
|
212
|
-
(0, react_jsx_runtime.jsx)("span", {
|
|
213
|
-
className: SubagentHeaderLineage_module_css_default.content,
|
|
214
|
-
children: (0, react_jsx_runtime.jsx)("span", {
|
|
215
|
-
className: SubagentHeaderLineage_module_css_default.label,
|
|
216
|
-
children: t("loading.label")
|
|
217
|
-
})
|
|
218
|
-
})
|
|
219
|
-
]
|
|
220
|
-
})
|
|
221
|
-
}, 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;
|
|
222
161
|
}
|
|
223
162
|
/** Render one catalog level and recurse only through explicitly expanded rows. */
|
|
224
|
-
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]);
|
|
225
175
|
const emptyLoading = catalog.state === "loading" && catalog.entries.length === 0;
|
|
226
|
-
const reserveDisclosure = catalog.entries.some((entry) => entry.
|
|
176
|
+
const reserveDisclosure = catalog.entries.some((entry) => !isKnownLeaf(catalogs[entry.id]));
|
|
227
177
|
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
228
|
-
emptyLoading && (0, react_jsx_runtime.jsx)(CatalogLoadingRows, {
|
|
229
|
-
parentSessionId,
|
|
230
|
-
summaries,
|
|
231
|
-
level,
|
|
232
|
-
t
|
|
233
|
-
}),
|
|
178
|
+
emptyLoading && (0, react_jsx_runtime.jsx)(CatalogLoadingRows, { t }),
|
|
234
179
|
catalog.state === "error" && (0, react_jsx_runtime.jsxs)("div", {
|
|
235
180
|
className: SubagentHeaderLineage_module_css_default.error,
|
|
236
181
|
children: [(0, react_jsx_runtime.jsx)("span", { children: catalog.error?.message ?? t("load.error") }), (0, react_jsx_runtime.jsxs)("button", {
|
|
237
182
|
type: "button",
|
|
238
183
|
className: SubagentHeaderLineage_module_css_default.refresh,
|
|
239
184
|
onClick: () => {
|
|
240
|
-
|
|
185
|
+
refreshProjection(parentSessionId);
|
|
241
186
|
},
|
|
242
|
-
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")]
|
|
243
188
|
})]
|
|
244
189
|
}),
|
|
245
190
|
catalog.entries.map((entry) => {
|
|
246
|
-
if (entry.kind === "diagnostic") {
|
|
247
|
-
const reason = diagnosticReason(entry, t);
|
|
248
|
-
return (0, react_jsx_runtime.jsx)("div", {
|
|
249
|
-
className: SubagentHeaderLineage_module_css_default.node,
|
|
250
|
-
children: (0, react_jsx_runtime.jsxs)("div", {
|
|
251
|
-
role: "treeitem",
|
|
252
|
-
"aria-disabled": "true",
|
|
253
|
-
"aria-level": level,
|
|
254
|
-
"aria-label": `${entry.id} ${reason}`,
|
|
255
|
-
className: `${SubagentHeaderLineage_module_css_default.row} ${SubagentHeaderLineage_module_css_default.disabled}`,
|
|
256
|
-
title: reason,
|
|
257
|
-
children: [
|
|
258
|
-
reserveDisclosure && (0, react_jsx_runtime.jsx)("span", { className: SubagentHeaderLineage_module_css_default.disclosureSpace }),
|
|
259
|
-
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "error" }),
|
|
260
|
-
(0, react_jsx_runtime.jsxs)("span", {
|
|
261
|
-
className: SubagentHeaderLineage_module_css_default.content,
|
|
262
|
-
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
263
|
-
className: SubagentHeaderLineage_module_css_default.label,
|
|
264
|
-
children: entry.id
|
|
265
|
-
}), (0, react_jsx_runtime.jsx)("span", {
|
|
266
|
-
className: SubagentHeaderLineage_module_css_default.summary,
|
|
267
|
-
children: reason
|
|
268
|
-
})]
|
|
269
|
-
})
|
|
270
|
-
]
|
|
271
|
-
})
|
|
272
|
-
}, entry.id);
|
|
273
|
-
}
|
|
274
191
|
const childCatalog = catalogs[entry.id];
|
|
275
192
|
const isCurrent = entry.id === currentSessionId;
|
|
276
193
|
const isExpanded = expanded.has(entry.id);
|
|
277
|
-
const knownLeaf =
|
|
194
|
+
const knownLeaf = isKnownLeaf(childCatalog);
|
|
278
195
|
const childLoading = childCatalog === void 0 || childCatalog.state === "loading" && childCatalog.entries.length === 0;
|
|
279
196
|
const summary = summaries[entry.id];
|
|
280
197
|
const label = entry.label ?? entry.id;
|
|
281
|
-
const mode = entry.mode === "one-shot" ? t("mode.oneShot") : t("mode.continuable");
|
|
282
|
-
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");
|
|
283
201
|
const secondary = [
|
|
284
202
|
summary?.title,
|
|
285
203
|
mode,
|
|
@@ -349,11 +267,14 @@ window.__ModuleLoader__.load({
|
|
|
349
267
|
className: `${SubagentHeaderLineage_module_css_default.disclosure} ${isExpanded ? SubagentHeaderLineage_module_css_default.disclosureOpen : ""}`,
|
|
350
268
|
"aria-label": t(isExpanded ? "branch.collapse" : "branch.expand", { label }),
|
|
351
269
|
onClick: toggle,
|
|
352
|
-
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, {})
|
|
353
271
|
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
354
272
|
className: SubagentHeaderLineage_module_css_default.clickarea,
|
|
355
273
|
children: [
|
|
356
|
-
(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
|
+
}),
|
|
357
278
|
(0, react_jsx_runtime.jsxs)("span", {
|
|
358
279
|
className: SubagentHeaderLineage_module_css_default.content,
|
|
359
280
|
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
@@ -384,7 +305,7 @@ window.__ModuleLoader__.load({
|
|
|
384
305
|
onKeyDown: (event) => {
|
|
385
306
|
event.stopPropagation();
|
|
386
307
|
},
|
|
387
|
-
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.
|
|
308
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular, {})
|
|
388
309
|
})
|
|
389
310
|
]
|
|
390
311
|
})]
|
|
@@ -392,12 +313,7 @@ window.__ModuleLoader__.load({
|
|
|
392
313
|
role: "group",
|
|
393
314
|
className: SubagentHeaderLineage_module_css_default.children,
|
|
394
315
|
"aria-busy": childLoading || void 0,
|
|
395
|
-
children: childCatalog === void 0 ? (0, react_jsx_runtime.jsx)(CatalogLoadingRows, {
|
|
396
|
-
parentSessionId: entry.id,
|
|
397
|
-
summaries,
|
|
398
|
-
level: level + 1,
|
|
399
|
-
t
|
|
400
|
-
}) : (0, react_jsx_runtime.jsx)(CatalogRows, {
|
|
316
|
+
children: childCatalog === void 0 ? (0, react_jsx_runtime.jsx)(CatalogLoadingRows, { t }) : (0, react_jsx_runtime.jsx)(CatalogRows, {
|
|
401
317
|
parentSessionId: entry.id,
|
|
402
318
|
currentSessionId,
|
|
403
319
|
catalog: childCatalog,
|
|
@@ -405,10 +321,9 @@ window.__ModuleLoader__.load({
|
|
|
405
321
|
summaries,
|
|
406
322
|
expanded,
|
|
407
323
|
level: level + 1,
|
|
408
|
-
now,
|
|
409
324
|
openChild,
|
|
410
325
|
openChildAside,
|
|
411
|
-
|
|
326
|
+
refreshProjection,
|
|
412
327
|
toggleBranch,
|
|
413
328
|
closeCatalog,
|
|
414
329
|
t
|
|
@@ -429,46 +344,44 @@ window.__ModuleLoader__.load({
|
|
|
429
344
|
};
|
|
430
345
|
}
|
|
431
346
|
/** One trigger-plus-tree dropdown over the catalog rooted at `rootSessionId`. */
|
|
432
|
-
function CatalogDropdown({ rootSessionId, currentSessionId, displayTitle, openTitle, variant,
|
|
347
|
+
function CatalogDropdown({ rootSessionId, currentSessionId, displayTitle, openTitle, variant, useSessions, useSessionStatus, openChild, openChildAside, refreshProjection, t }) {
|
|
433
348
|
const ancestorSwitcher = variant === "switcher" && openTitle !== void 0;
|
|
434
|
-
const
|
|
349
|
+
const projections = useSessions((state) => state.projectionsBySession);
|
|
435
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
|
+
]);
|
|
436
364
|
const catalog = catalogs[rootSessionId];
|
|
437
365
|
const [open, setOpen] = (0, react.useState)(false);
|
|
438
366
|
const [menuPosition, setMenuPosition] = (0, react.useState)();
|
|
439
|
-
const [now, setNow] = (0, react.useState)(() => Date.now());
|
|
440
367
|
const [expanded, setExpanded] = (0, react.useState)(() => /* @__PURE__ */ new Set());
|
|
441
368
|
const rootRef = (0, react.useRef)(null);
|
|
442
369
|
const triggerRef = (0, react.useRef)(null);
|
|
443
370
|
const menuRef = (0, react.useRef)(null);
|
|
444
371
|
const hoverOpenTimer = (0, react.useRef)(void 0);
|
|
445
372
|
const hoverCloseTimer = (0, react.useRef)(void 0);
|
|
446
|
-
const
|
|
447
|
-
const
|
|
448
|
-
|
|
449
|
-
const
|
|
450
|
-
const
|
|
451
|
-
const
|
|
452
|
-
const
|
|
453
|
-
const
|
|
454
|
-
const totalCountKey = descendantCount === 1 ? "count.total.one" : "count.total.other";
|
|
455
|
-
const runningCountKey = descendants.runningCount === 1 ? "count.running.one" : "count.running.other";
|
|
456
|
-
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" ? {
|
|
457
381
|
entries: [],
|
|
458
|
-
parentAvailable: catalog?.parentAvailable ?? false,
|
|
459
382
|
state: "loading",
|
|
460
383
|
error: null
|
|
461
|
-
} :
|
|
462
|
-
const observeCatalog = (parentSessionId, next) => {
|
|
463
|
-
if (next) observedCatalogs.current.add(parentSessionId);
|
|
464
|
-
else observedCatalogs.current.delete(parentSessionId);
|
|
465
|
-
setCatalogOpen(parentSessionId, next);
|
|
466
|
-
};
|
|
467
|
-
const closeAllCatalogs = () => {
|
|
468
|
-
for (const parentSessionId of observedCatalogs.current) setCatalogOpen(parentSessionId, false);
|
|
469
|
-
observedCatalogs.current.clear();
|
|
470
|
-
setExpanded(/* @__PURE__ */ new Set());
|
|
471
|
-
};
|
|
384
|
+
} : void 0);
|
|
472
385
|
const cancelHoverClose = () => {
|
|
473
386
|
if (hoverCloseTimer.current === void 0) return;
|
|
474
387
|
clearTimeout(hoverCloseTimer.current);
|
|
@@ -488,12 +401,10 @@ window.__ModuleLoader__.load({
|
|
|
488
401
|
if (trigger === null) return;
|
|
489
402
|
setOpen(true);
|
|
490
403
|
setMenuPosition(catalogMenuPosition(trigger));
|
|
491
|
-
setNow(Date.now());
|
|
492
|
-
observeCatalog(rootSessionId, true);
|
|
493
404
|
} else {
|
|
494
405
|
setOpen(false);
|
|
495
406
|
setMenuPosition(void 0);
|
|
496
|
-
|
|
407
|
+
setExpanded(/* @__PURE__ */ new Set());
|
|
497
408
|
}
|
|
498
409
|
if (restoreFocus) queueMicrotask(() => {
|
|
499
410
|
triggerRef.current?.focus();
|
|
@@ -522,10 +433,9 @@ window.__ModuleLoader__.load({
|
|
|
522
433
|
if (closing.has(parentSessionId) || !expanded.has(parentSessionId)) return;
|
|
523
434
|
closing.add(parentSessionId);
|
|
524
435
|
const branch = catalogs[parentSessionId];
|
|
525
|
-
for (const entry of branch?.entries ?? [])
|
|
436
|
+
for (const entry of branch?.entries ?? []) visit(entry.id);
|
|
526
437
|
};
|
|
527
438
|
visit(root);
|
|
528
|
-
for (const parentSessionId of closing) observeCatalog(parentSessionId, false);
|
|
529
439
|
setExpanded((current) => new Set([...current].filter((id) => !closing.has(id))));
|
|
530
440
|
};
|
|
531
441
|
const toggleBranch = (childSessionId) => {
|
|
@@ -534,7 +444,7 @@ window.__ModuleLoader__.load({
|
|
|
534
444
|
return;
|
|
535
445
|
}
|
|
536
446
|
setExpanded((current) => new Set(current).add(childSessionId));
|
|
537
|
-
|
|
447
|
+
refreshProjection(childSessionId);
|
|
538
448
|
};
|
|
539
449
|
(0, react.useEffect)(() => {
|
|
540
450
|
if (!open) return;
|
|
@@ -561,29 +471,18 @@ window.__ModuleLoader__.load({
|
|
|
561
471
|
document.removeEventListener("scroll", placeMenu, true);
|
|
562
472
|
};
|
|
563
473
|
}, [open]);
|
|
564
|
-
(0, react.useEffect)(() => {
|
|
565
|
-
if (!open || descendants.runningCount === 0) return;
|
|
566
|
-
const timer = setInterval(() => {
|
|
567
|
-
setNow(Date.now());
|
|
568
|
-
}, 1e3);
|
|
569
|
-
return () => {
|
|
570
|
-
clearInterval(timer);
|
|
571
|
-
};
|
|
572
|
-
}, [open, descendants.runningCount]);
|
|
573
474
|
(0, react.useEffect)(() => () => {
|
|
574
475
|
cancelHoverOpen();
|
|
575
476
|
cancelHoverClose();
|
|
576
|
-
for (const parentSessionId of observedCatalogs.current) setCatalogOpenRef.current(parentSessionId, false);
|
|
577
|
-
observedCatalogs.current.clear();
|
|
578
477
|
}, []);
|
|
579
|
-
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);
|
|
580
479
|
(0, react.useEffect)(() => {
|
|
581
480
|
if (visible) return;
|
|
582
481
|
cancelHoverOpen();
|
|
583
482
|
cancelHoverClose();
|
|
584
483
|
if (!open) return;
|
|
585
484
|
setOpen(false);
|
|
586
|
-
|
|
485
|
+
setExpanded(/* @__PURE__ */ new Set());
|
|
587
486
|
}, [visible, open]);
|
|
588
487
|
if (!visible) return null;
|
|
589
488
|
const focusAt = (index) => {
|
|
@@ -617,96 +516,105 @@ window.__ModuleLoader__.load({
|
|
|
617
516
|
onKeyDown: navigate,
|
|
618
517
|
onMouseEnter: scheduleHoverOpen,
|
|
619
518
|
onMouseLeave: scheduleHoverClose,
|
|
620
|
-
children: [
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
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);
|
|
644
571
|
},
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
}) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [descendants.runningCount > 0 && (0, react_jsx_runtime.jsx)("span", {
|
|
649
|
-
className: SubagentHeaderLineage_module_css_default.activitySlot,
|
|
650
|
-
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "ongoing" })
|
|
651
|
-
}), (0, react_jsx_runtime.jsx)("span", {
|
|
652
|
-
className: SubagentHeaderLineage_module_css_default.count,
|
|
653
|
-
children: t(totalCountKey, { count: descendantCount })
|
|
654
|
-
})] }), 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 })]
|
|
655
|
-
}),
|
|
656
|
-
open && (0, react_dom.createPortal)((0, react_jsx_runtime.jsx)("div", {
|
|
657
|
-
ref: menuRef,
|
|
658
|
-
className: SubagentHeaderLineage_module_css_default.menu,
|
|
659
|
-
style: menuPosition,
|
|
660
|
-
role: "tree",
|
|
661
|
-
"aria-label": t("tree.aria"),
|
|
662
|
-
onMouseEnter: cancelHoverClose,
|
|
663
|
-
onMouseLeave: scheduleHoverClose,
|
|
664
|
-
children: (0, react_jsx_runtime.jsx)(CatalogRows, {
|
|
665
|
-
parentSessionId: rootSessionId,
|
|
666
|
-
currentSessionId,
|
|
667
|
-
catalog: presentedCatalog,
|
|
668
|
-
catalogs,
|
|
669
|
-
summaries,
|
|
670
|
-
expanded,
|
|
671
|
-
level: 1,
|
|
672
|
-
now,
|
|
673
|
-
openChild,
|
|
674
|
-
openChildAside,
|
|
675
|
-
refresh,
|
|
676
|
-
toggleBranch,
|
|
677
|
-
closeCatalog: () => {
|
|
678
|
-
changeOpen(false);
|
|
679
|
-
},
|
|
680
|
-
t
|
|
681
|
-
})
|
|
682
|
-
}), document.body)
|
|
683
|
-
]
|
|
572
|
+
t
|
|
573
|
+
})
|
|
574
|
+
}), document.body)]
|
|
684
575
|
});
|
|
685
576
|
}
|
|
686
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
|
+
/**
|
|
687
599
|
* Render one breadcrumb title together with its subagent navigation.
|
|
688
600
|
* @param props - Breadcrumb title, session standard props, and catalog actions.
|
|
689
|
-
* @returns
|
|
601
|
+
* @returns A title-and-chevron sibling switcher, or nothing on a root session.
|
|
690
602
|
*/
|
|
691
|
-
function SubagentHeaderLineage({ lineageSessionId, displayTitle, openTitle, useSessions, openChild, openChildAside,
|
|
603
|
+
function SubagentHeaderLineage({ lineageSessionId, displayTitle, openTitle, useSessions, useSession, useSessionStatus, openChild, openChildAside, refreshProjection, t }) {
|
|
604
|
+
const address = useSession((session) => session.subagent?.address);
|
|
692
605
|
const parentId = useSessions((state) => {
|
|
693
|
-
|
|
694
|
-
|
|
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;
|
|
695
608
|
});
|
|
696
609
|
const shared = {
|
|
697
610
|
useSessions,
|
|
611
|
+
useSessionStatus,
|
|
698
612
|
openChild,
|
|
699
613
|
openChildAside,
|
|
700
|
-
|
|
701
|
-
setCatalogOpen,
|
|
614
|
+
refreshProjection,
|
|
702
615
|
t
|
|
703
616
|
};
|
|
704
|
-
if (parentId === void 0) return
|
|
705
|
-
rootSessionId: lineageSessionId,
|
|
706
|
-
variant: "count",
|
|
707
|
-
separator: true,
|
|
708
|
-
...shared
|
|
709
|
-
}, lineageSessionId);
|
|
617
|
+
if (parentId === void 0) return null;
|
|
710
618
|
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(CatalogDropdown, {
|
|
711
619
|
rootSessionId: parentId,
|
|
712
620
|
currentSessionId: lineageSessionId,
|
|
@@ -744,7 +652,7 @@ window.__ModuleLoader__.load({
|
|
|
744
652
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
745
653
|
className: SubagentReadOnlyComposer_module_css_default.frame,
|
|
746
654
|
role: "status",
|
|
747
|
-
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") })]
|
|
748
656
|
});
|
|
749
657
|
}
|
|
750
658
|
//#endregion
|
|
@@ -794,7 +702,7 @@ window.__ModuleLoader__.load({
|
|
|
794
702
|
if (parts.length !== 2 || parts[0] !== "session") return void 0;
|
|
795
703
|
const parentSessionId = url.searchParams.get("parent");
|
|
796
704
|
const mode = url.searchParams.get("mode");
|
|
797
|
-
if (parentSessionId === null || parentSessionId === "" || mode !== "one-shot" && mode !== "continuable") return;
|
|
705
|
+
if (parentSessionId === null || parentSessionId === "" || mode !== "one-shot" && mode !== "continuable" && mode !== "unknown") return;
|
|
798
706
|
try {
|
|
799
707
|
return {
|
|
800
708
|
parentSessionId,
|
|
@@ -823,8 +731,6 @@ window.__ModuleLoader__.load({
|
|
|
823
731
|
const address = parseSubagentChatAddress(resourceAddress);
|
|
824
732
|
if (address === void 0) throw new Error(`ui-subagent: invalid chat resource address "${resourceAddress}"`);
|
|
825
733
|
if (isAbortRequested(signal)) return;
|
|
826
|
-
await sessions.refreshSubagents(address.parentSessionId);
|
|
827
|
-
if (isAbortRequested(signal)) return;
|
|
828
734
|
const reference = sessions.retain(address, {
|
|
829
735
|
source: "sidebarChat",
|
|
830
736
|
signal
|
|
@@ -910,9 +816,6 @@ window.__ModuleLoader__.load({
|
|
|
910
816
|
const NS = "subagent";
|
|
911
817
|
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
912
818
|
const zh = {
|
|
913
|
-
"diagnostic.corrupt": "会话记录损坏",
|
|
914
|
-
"diagnostic.unsupported": "子代理记录版本不受支持",
|
|
915
|
-
"diagnostic.unavailable": "会话记录暂不可用",
|
|
916
819
|
"duration.seconds": "{seconds}秒",
|
|
917
820
|
"duration.minutes": "{minutes}分{seconds}秒",
|
|
918
821
|
"duration.hours": "{hours}小时{minutes}分{seconds}秒",
|
|
@@ -928,12 +831,14 @@ window.__ModuleLoader__.load({
|
|
|
928
831
|
"tokens.million": "{value}M",
|
|
929
832
|
"tokens.total": "{value} tok",
|
|
930
833
|
"loading.label": "正在加载子代理…",
|
|
931
|
-
"loading.aria": "正在加载子代理",
|
|
932
834
|
"load.error": "无法加载子代理",
|
|
933
835
|
"retry": "重试",
|
|
934
836
|
"mode.oneShot": "一次性",
|
|
935
837
|
"mode.continuable": "可继续",
|
|
838
|
+
"mode.unknown": "模式未知",
|
|
839
|
+
"readonly.unknown.body": "读取子会话后才能确定是否可继续。",
|
|
936
840
|
"activity.running": "正在运行",
|
|
841
|
+
"activity.completed": "已完成",
|
|
937
842
|
"activity.inactive": "当前未运行",
|
|
938
843
|
"branch.collapse": "收起 {label} 的下级子代理",
|
|
939
844
|
"branch.expand": "展开 {label} 的下级子代理",
|
|
@@ -952,9 +857,6 @@ window.__ModuleLoader__.load({
|
|
|
952
857
|
};
|
|
953
858
|
/** English dictionary, key-identical to the Chinese source of truth. */
|
|
954
859
|
const en = {
|
|
955
|
-
"diagnostic.corrupt": "corrupted session record",
|
|
956
|
-
"diagnostic.unsupported": "unsupported subagent record version",
|
|
957
|
-
"diagnostic.unavailable": "session record temporarily unavailable",
|
|
958
860
|
"duration.seconds": "{seconds}s",
|
|
959
861
|
"duration.minutes": "{minutes}m {seconds}s",
|
|
960
862
|
"duration.hours": "{hours}h {minutes}m {seconds}s",
|
|
@@ -970,12 +872,14 @@ window.__ModuleLoader__.load({
|
|
|
970
872
|
"tokens.million": "{value}M",
|
|
971
873
|
"tokens.total": "{value} tok",
|
|
972
874
|
"loading.label": "Loading subagents…",
|
|
973
|
-
"loading.aria": "Loading subagents",
|
|
974
875
|
"load.error": "Unable to load subagents",
|
|
975
876
|
"retry": "Retry",
|
|
976
877
|
"mode.oneShot": "one-shot",
|
|
977
878
|
"mode.continuable": "continuable",
|
|
879
|
+
"mode.unknown": "unknown mode",
|
|
880
|
+
"readonly.unknown.body": "Read the child session to determine whether it can be continued.",
|
|
978
881
|
"activity.running": "running",
|
|
882
|
+
"activity.completed": "completed",
|
|
979
883
|
"activity.inactive": "not running",
|
|
980
884
|
"branch.collapse": "Collapse {label} descendants",
|
|
981
885
|
"branch.expand": "Expand {label} descendants",
|
|
@@ -1006,6 +910,7 @@ window.__ModuleLoader__.load({
|
|
|
1006
910
|
function selectReadOnlySubagent(owner) {
|
|
1007
911
|
const subagent = owner.session?.subagent;
|
|
1008
912
|
if (subagent === void 0 || subagent === null) return null;
|
|
913
|
+
if (subagent.address.mode === "unknown") return { reason: "unknown" };
|
|
1009
914
|
if (subagent.address.mode === "one-shot") return { reason: "one-shot" };
|
|
1010
915
|
if (subagent.parentAvailable !== false) return null;
|
|
1011
916
|
return owner.session?.running === true ? null : { reason: "parent-unavailable" };
|
|
@@ -1022,7 +927,6 @@ window.__ModuleLoader__.load({
|
|
|
1022
927
|
ctx.inject(["resources", "sidebarRightTabs"], (scope) => {
|
|
1023
928
|
registerSidebarChat(scope, ctx.locale.bind(NS));
|
|
1024
929
|
});
|
|
1025
|
-
const sessions = ctx.sessions;
|
|
1026
930
|
const catalogActions = (_parentSessionId) => ({
|
|
1027
931
|
openChild(address) {
|
|
1028
932
|
ctx.uiWorkspace.openSession(address);
|
|
@@ -1033,11 +937,8 @@ window.__ModuleLoader__.load({
|
|
|
1033
937
|
preferNewPane: true
|
|
1034
938
|
});
|
|
1035
939
|
},
|
|
1036
|
-
|
|
1037
|
-
sessions.
|
|
1038
|
-
},
|
|
1039
|
-
setCatalogOpen(parentSessionId, open) {
|
|
1040
|
-
sessions.setSubagentCatalogOpen(parentSessionId, open);
|
|
940
|
+
refreshProjection(parentSessionId) {
|
|
941
|
+
ctx.sessions.refreshProjections(parentSessionId);
|
|
1041
942
|
}
|
|
1042
943
|
});
|
|
1043
944
|
ctx.slots.inject("conversation.session.header.lineage", () => ctx.slots.register({
|
|
@@ -1045,6 +946,13 @@ window.__ModuleLoader__.load({
|
|
|
1045
946
|
locale: NS,
|
|
1046
947
|
inject: catalogActions
|
|
1047
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));
|
|
1048
956
|
ctx.slots.inject("conversation.composer", () => ctx.slots.register({
|
|
1049
957
|
name: "conversation.composer",
|
|
1050
958
|
priority: -10,
|
|
@@ -6,15 +6,25 @@ import { NS } from './locales.ts';
|
|
|
6
6
|
export interface SubagentCatalogInjected {
|
|
7
7
|
openChild: (address: SubagentAddress) => void;
|
|
8
8
|
openChildAside: (address: SubagentAddress) => void;
|
|
9
|
-
|
|
10
|
-
setCatalogOpen: (parentSessionId: SessionId, open: boolean) => void;
|
|
9
|
+
refreshProjection: (parentSessionId: SessionId) => void;
|
|
11
10
|
}
|
|
12
11
|
/** Full props for the session-header lineage renderer. */
|
|
13
12
|
export type SubagentHeaderLineageProps = PropsRuntime<'conversation.session.header.lineage'> & SubagentCatalogInjected & PropsLocale<typeof NS>;
|
|
13
|
+
/** Full props for the root-session catalog entry in the header actions band. */
|
|
14
|
+
export type SubagentCatalogActionProps = PropsRuntime<'conversation.session.header.actions'> & SubagentCatalogInjected & PropsLocale<typeof NS>;
|
|
15
|
+
/**
|
|
16
|
+
* Session-header catalog action for root sessions: the descendant count and
|
|
17
|
+
* its dropdown, ordered after the task list. Child sessions render nothing
|
|
18
|
+
* here — their breadcrumb switcher in the lineage slot owns the same
|
|
19
|
+
* navigation.
|
|
20
|
+
* @param props - Session standard props plus the catalog actions and translator.
|
|
21
|
+
* @returns The count dropdown, or null on a child session.
|
|
22
|
+
*/
|
|
23
|
+
export declare function SubagentCatalogAction({ sessionId, useSessions, useSessionStatus, openChild, openChildAside, refreshProjection, t, }: SubagentCatalogActionProps): import("react").JSX.Element | null;
|
|
14
24
|
/**
|
|
15
25
|
* Render one breadcrumb title together with its subagent navigation.
|
|
16
26
|
* @param props - Breadcrumb title, session standard props, and catalog actions.
|
|
17
|
-
* @returns
|
|
27
|
+
* @returns A title-and-chevron sibling switcher, or nothing on a root session.
|
|
18
28
|
*/
|
|
19
|
-
export declare function SubagentHeaderLineage({ lineageSessionId, displayTitle, openTitle, useSessions, openChild, openChildAside,
|
|
29
|
+
export declare function SubagentHeaderLineage({ lineageSessionId, displayTitle, openTitle, useSessions, useSession, useSessionStatus, openChild, openChildAside, refreshProjection, t, }: SubagentHeaderLineageProps): import("react").JSX.Element | null;
|
|
20
30
|
//# sourceMappingURL=SubagentHeaderLineage.d.ts.map
|
|
@@ -2,7 +2,7 @@ import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots
|
|
|
2
2
|
import { NS } from './locales.ts';
|
|
3
3
|
/** Why a catalog-addressed conversation cannot accept human input. */
|
|
4
4
|
export interface SubagentReadOnlyMatch {
|
|
5
|
-
reason: 'one-shot' | 'parent-unavailable';
|
|
5
|
+
reason: 'one-shot' | 'parent-unavailable' | 'unknown';
|
|
6
6
|
}
|
|
7
7
|
/** Full chain props after the read-only subagent selector accepts the owner currency. */
|
|
8
8
|
export type SubagentReadOnlyComposerProps = PropsRuntime<'conversation.composer'> & {
|
|
@@ -7,7 +7,7 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
|
7
7
|
'subagent': SubagentKey;
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
|
-
export type { SubagentCatalogInjected, SubagentHeaderLineageProps, } from './SubagentHeaderLineage.tsx';
|
|
10
|
+
export type { SubagentCatalogActionProps, SubagentCatalogInjected, SubagentHeaderLineageProps, } from './SubagentHeaderLineage.tsx';
|
|
11
11
|
export type { SubagentReadOnlyComposerProps, SubagentReadOnlyMatch, } from './SubagentReadOnlyComposer.tsx';
|
|
12
12
|
/** Required services for subagent presentation and navigation. */
|
|
13
13
|
export declare const inject: string[];
|
|
@@ -3,9 +3,6 @@
|
|
|
3
3
|
export declare const NS = "subagent";
|
|
4
4
|
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
5
5
|
export declare const zh: {
|
|
6
|
-
readonly 'diagnostic.corrupt': "会话记录损坏";
|
|
7
|
-
readonly 'diagnostic.unsupported': "子代理记录版本不受支持";
|
|
8
|
-
readonly 'diagnostic.unavailable': "会话记录暂不可用";
|
|
9
6
|
readonly 'duration.seconds': "{seconds}秒";
|
|
10
7
|
readonly 'duration.minutes': "{minutes}分{seconds}秒";
|
|
11
8
|
readonly 'duration.hours': "{hours}小时{minutes}分{seconds}秒";
|
|
@@ -21,12 +18,14 @@ export declare const zh: {
|
|
|
21
18
|
readonly 'tokens.million': "{value}M";
|
|
22
19
|
readonly 'tokens.total': "{value} tok";
|
|
23
20
|
readonly 'loading.label': "正在加载子代理…";
|
|
24
|
-
readonly 'loading.aria': "正在加载子代理";
|
|
25
21
|
readonly 'load.error': "无法加载子代理";
|
|
26
22
|
readonly retry: "重试";
|
|
27
23
|
readonly 'mode.oneShot': "一次性";
|
|
28
24
|
readonly 'mode.continuable': "可继续";
|
|
25
|
+
readonly 'mode.unknown': "模式未知";
|
|
26
|
+
readonly 'readonly.unknown.body': "读取子会话后才能确定是否可继续。";
|
|
29
27
|
readonly 'activity.running': "正在运行";
|
|
28
|
+
readonly 'activity.completed': "已完成";
|
|
30
29
|
readonly 'activity.inactive': "当前未运行";
|
|
31
30
|
readonly 'branch.collapse': "收起 {label} 的下级子代理";
|
|
32
31
|
readonly 'branch.expand': "展开 {label} 的下级子代理";
|
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.
|
|
4
|
+
"version": "0.1.7-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -43,31 +43,31 @@
|
|
|
43
43
|
},
|
|
44
44
|
"license": "MIT",
|
|
45
45
|
"peerDependencies": {
|
|
46
|
-
"@deepseek-ai/cordis": "
|
|
46
|
+
"@deepseek-ai/cordis": "~4.0.4"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@types/react": "~18.3.1",
|
|
50
50
|
"@types/react-dom": "~18.3.0",
|
|
51
51
|
"react": "^18.2.0",
|
|
52
52
|
"react-dom": "^18.2.0",
|
|
53
|
-
"@deepseek-ai/dsh-client-
|
|
54
|
-
"@deepseek-ai/dsh-client-
|
|
55
|
-
"@deepseek-ai/dsh-client-
|
|
56
|
-
"@deepseek-ai/dsh-client-ui-chat": "
|
|
57
|
-
"@deepseek-ai/dsh-client-ui-conversation": "
|
|
58
|
-
"@deepseek-ai/dsh-client-ui-input-trigger": "
|
|
59
|
-
"@deepseek-ai/dsh-client-ui-
|
|
60
|
-
"@deepseek-ai/dsh-
|
|
61
|
-
"@deepseek-ai/dsh-
|
|
62
|
-
"@deepseek-ai/
|
|
63
|
-
"@deepseek-ai/
|
|
64
|
-
"@deepseek-ai/dsh-client-connection": "
|
|
65
|
-
"@deepseek-ai/dsh-session": "
|
|
66
|
-
"@deepseek-ai/dsh-client-ui-renderer": "
|
|
67
|
-
"@deepseek-ai/dsh-client-ui-sidebar-right": "
|
|
68
|
-
"@deepseek-ai/dsh-client-ui-session": "
|
|
69
|
-
"@deepseek-ai/dsh-client-ui-workspace": "
|
|
70
|
-
"@deepseek-ai/dsh-api-session-controller": "
|
|
53
|
+
"@deepseek-ai/dsh-client-locale": "0.1.7-alpha.2",
|
|
54
|
+
"@deepseek-ai/dsh-client-resources": "0.1.7-alpha.2",
|
|
55
|
+
"@deepseek-ai/dsh-client-test-runtime": "0.1.7-alpha.2",
|
|
56
|
+
"@deepseek-ai/dsh-client-ui-chat": "0.1.7-alpha.2",
|
|
57
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.1.7-alpha.2",
|
|
58
|
+
"@deepseek-ai/dsh-client-ui-input-trigger": "0.1.7-alpha.2",
|
|
59
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.7-alpha.2",
|
|
60
|
+
"@deepseek-ai/dsh-token-meter": "0.1.7-alpha.2",
|
|
61
|
+
"@deepseek-ai/dsh-subagent": "0.1.7-alpha.2",
|
|
62
|
+
"@deepseek-ai/cordis": "~4.0.4",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.1.7-alpha.2",
|
|
64
|
+
"@deepseek-ai/dsh-client-connection": "0.1.7-alpha.2",
|
|
65
|
+
"@deepseek-ai/dsh-session": "0.1.7-alpha.2",
|
|
66
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.1.7-alpha.2",
|
|
67
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right": "0.1.7-alpha.2",
|
|
68
|
+
"@deepseek-ai/dsh-client-ui-session": "0.1.7-alpha.2",
|
|
69
|
+
"@deepseek-ai/dsh-client-ui-workspace": "0.1.7-alpha.2",
|
|
70
|
+
"@deepseek-ai/dsh-api-session-controller": "0.1.7-alpha.2"
|
|
71
71
|
},
|
|
72
72
|
"files": [
|
|
73
73
|
"lib/index.js",
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/** UI Subagent-owned projection of descendant counts from Session summaries. */
|
|
2
|
-
import type { SessionId } from '@deepseek-ai/dsh-session/types';
|
|
3
|
-
interface LineageEntry {
|
|
4
|
-
readonly id: SessionId;
|
|
5
|
-
readonly parentId?: SessionId;
|
|
6
|
-
readonly origin?: 'subagent';
|
|
7
|
-
readonly running: boolean;
|
|
8
|
-
}
|
|
9
|
-
/** Descendant counts for one possible parent Session. */
|
|
10
|
-
export interface SubagentDescendantSummary {
|
|
11
|
-
readonly count: number;
|
|
12
|
-
readonly runningCount: number;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Index uninterrupted subagent descendants under each ancestor.
|
|
16
|
-
* @param summaries - Session summaries keyed by id.
|
|
17
|
-
* @returns descendant totals keyed by possible parent id.
|
|
18
|
-
*/
|
|
19
|
-
export declare function indexSubagentDescendants(summaries: Readonly<Record<SessionId, LineageEntry>>): ReadonlyMap<SessionId, SubagentDescendantSummary>;
|
|
20
|
-
export {};
|
|
21
|
-
//# sourceMappingURL=subagent-lineage.d.ts.map
|