@deepseek-ai/dsh-client-ui-chat 0.1.6-alpha.1 → 0.1.7-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +64 -10
- package/README.zh.md +62 -10
- package/lib/client.js +4835 -1405
- package/lib/index.js +37 -10
- package/lib/types/chat-settings.d.ts +41 -8
- package/lib/types/client/chat/AssistantMarkdown.d.ts +15 -12
- package/lib/types/client/chat/AssistantNodeView.d.ts +5 -2
- package/lib/types/client/chat/ChatGroupSeat.d.ts +14 -0
- package/lib/types/client/chat/ChatNodeSeat.d.ts +11 -5
- package/lib/types/client/chat/ChatView.d.ts +1 -1
- package/lib/types/client/chat/GenericCommandCard.d.ts +6 -1
- package/lib/types/client/chat/ReasoningRow.d.ts +13 -7
- package/lib/types/client/chat/StatsPills.d.ts +4 -4
- package/lib/types/client/chat/TurnNavigator.d.ts +11 -9
- package/lib/types/client/chat/TurnTailNodeView.d.ts +4 -4
- package/lib/types/client/chat/TurnTriggerNodeView.d.ts +4 -0
- package/lib/types/client/chat/TurnUsagePanel.d.ts +1 -16
- package/lib/types/client/chat/message-chrome.d.ts +9 -6
- package/lib/types/client/chat/register-node-renderers.d.ts +8 -1
- package/lib/types/client/chat/render-entry.d.ts +9 -0
- package/lib/types/client/chat/step-process.d.ts +11 -0
- package/lib/types/client/chat/turn-trigger.d.ts +15 -0
- package/lib/types/client/chat/use-chat-navigation.d.ts +69 -0
- package/lib/types/client/chat/use-chat-reading.d.ts +95 -0
- package/lib/types/client/chat/use-chat-scroll.d.ts +35 -0
- package/lib/types/client/chat/use-chat-viewport.d.ts +147 -0
- package/lib/types/client/chat/use-disclosure.d.ts +15 -0
- package/lib/types/client/contract/chat-nodes.d.ts +0 -2
- package/lib/types/client/contract/chat-visibility.d.ts +9 -0
- package/lib/types/client/contract/process-groups.d.ts +23 -0
- package/lib/types/client/contract/slots.d.ts +60 -14
- package/lib/types/client/contract/snapshot.d.ts +14 -1
- package/lib/types/client/contract/turn-metrics.d.ts +1 -20
- package/lib/types/client/contract/turn-process.d.ts +7 -0
- package/lib/types/client/conversation-nodes/assistant.d.ts +1 -2
- package/lib/types/client/conversation-nodes/chat-snapshot-builder.d.ts +9 -2
- package/lib/types/client/conversation-nodes/inbox.d.ts +16 -6
- package/lib/types/client/conversation-nodes/message.d.ts +5 -1
- package/lib/types/client/conversation-nodes/process-activity.d.ts +10 -0
- package/lib/types/client/conversation-nodes/process-groups.d.ts +27 -0
- package/lib/types/client/index.d.ts +3 -1
- package/lib/types/client/locale.d.ts +106 -12
- package/lib/types/client/performance-usage.d.ts +19 -0
- package/lib/types/client/presentation-policy.d.ts +35 -0
- package/lib/types/client/settings/LinkOpeningRow.d.ts +24 -0
- package/lib/types/client/settings/PerformanceUsageRow.d.ts +18 -0
- package/lib/types/client/settings/PreferenceRow.d.ts +17 -0
- package/lib/types/client/settings/TranscriptViewRow.d.ts +6 -6
- package/lib/types/client/transcript-view.d.ts +8 -5
- package/lib/types/index.d.ts +26 -4
- package/package.json +40 -35
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-chat/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 14a5260e23640d58c73779cff76bd27853bf4685
|
|
6
|
+
README.zh.md: 94e1442c5a1afbe3e57df8e2ac2e22181becf253
|
package/README.md
CHANGED
|
@@ -8,17 +8,19 @@ English | [中文](README.zh.md)
|
|
|
8
8
|
|
|
9
9
|
## Summary
|
|
10
10
|
|
|
11
|
-
Use this package to render a browser chat from recorded Session conversations, including historical images, localized actions, and restored scroll position.
|
|
11
|
+
Use this package to render a browser chat from recorded Session conversations, including historical images, localized actions, and restored scroll position. Work-details modes control reasoning previews and fold eligible completed-turn process rows without hiding final answers. Local transcript and steering submissions appear immediately, remain in their original surface, and disappear atomically when authoritative Session records arrive, while queued submissions stay outside Chat. The package does not assemble or modify model requests.
|
|
12
12
|
|
|
13
13
|
File-mention providers receive the viewed Session ID with the closing-turn owner, so links into inherited history can address the fork itself.
|
|
14
14
|
|
|
15
15
|
## Table of Contents
|
|
16
16
|
|
|
17
17
|
- [Reference previews](#reference-previews)
|
|
18
|
-
- [
|
|
18
|
+
- [Hidden Chat rows](#system-prompt-row)
|
|
19
|
+
- [Command and failure rows](#command-and-failure-rows)
|
|
19
20
|
- [Turn token usage](#turn-token-usage)
|
|
20
21
|
- [Completed-turn footer](#completed-turn-footer)
|
|
21
22
|
- [Turn Process Folding](#turn-process-folding)
|
|
23
|
+
- [Grouped rendering](#grouped-rendering)
|
|
22
24
|
- [Scroll ownership](#scroll-ownership)
|
|
23
25
|
- [Model Experience](#model-experience)
|
|
24
26
|
- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
|
|
@@ -29,40 +31,89 @@ File-mention providers receive the viewed Session ID with the closing-turn owner
|
|
|
29
31
|
<a id="reference-previews"></a>
|
|
30
32
|
## Reference previews
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
Chat supplies file and HTTP(S) navigation through one `MarkdownDelegateProvider` around its node list. Assistant Markdown file links open in the right Sidebar after the message settles, including references to unmodified files. Relative paths resolve in the viewed Session's workspace; absolute paths retain the same Session's filesystem access. `#L24` and `#L24-L30` navigate to the first specified line and reuse an existing file tab. Missing files show the preview's error state.
|
|
35
|
+
|
|
36
|
+
Settings → General → Open chat links in selects the destination for ordinary clicks on Chat HTTP(S) links: Built-in browser (default) opens a new right-Sidebar Browser tab, while New browser tab opens an external tab. The setting is shown only while the built-in browser is available. If the Sidebar Browser is not registered, both choices use the external browser; modified clicks retain native behavior. The `ui-chat.linkOpening` preference persists on loopback browsers and stays process-local when settings cannot persist writes. Sent file references and skills confirmed by the message’s logged invocation also open in the right Sidebar. File paths use the viewed Session; skill names resolve through its current input-trigger source. Both use the prose file-link dotted underline on hover or focus. Sessions, directories, and command labels remain non-navigating references.
|
|
33
37
|
|
|
34
38
|
<a id="system-prompt-row"></a>
|
|
35
|
-
##
|
|
39
|
+
## Hidden Chat rows
|
|
40
|
+
|
|
41
|
+
Chat omits system-prompt, ordinary Context injection, and `permission` command rows in every work-details mode. The filter changes neither recorded Session events nor Trajectory inspection. Non-human Turn triggers remain independent notices; other command rows remain in Chat.
|
|
42
|
+
|
|
43
|
+
When an Assistant attempt retires without a visible message, Chat hides its already-published Node instead of removing its key. A retry in the same Step reuses that key when visible content returns. This also applies when the loaded window lacks the Step start.
|
|
44
|
+
|
|
45
|
+
<a id="command-and-failure-rows"></a>
|
|
46
|
+
## Command and failure rows
|
|
36
47
|
|
|
37
|
-
|
|
48
|
+
Generic command rows retain the ordinary command glyph in every lifecycle state; failure remains explicit through the row state and summary. A terminal Turn failure remains a separate red-dot notice; intermediate model retries do not create that notice, and an output-token limit uses the amber warning dot.
|
|
49
|
+
|
|
50
|
+
-----
|
|
38
51
|
|
|
39
52
|
<a id="turn-token-usage"></a>
|
|
40
53
|
## Turn token usage
|
|
41
54
|
|
|
42
55
|
A completed Turn shows an expandable usage row only when the loaded window includes `turn/start` and every started model attempt reports safe, exact usage. The row omits unavailable optional buckets. Incomplete or contradictory accounting hides the complete disclosure instead of presenting a partial total.
|
|
43
56
|
|
|
44
|
-
|
|
57
|
+
Settings → General → Performance & usage stores `ui-chat.performanceUsage` as `detailed` (default) or `compact`. Compact shows only available output speed and cache-hit percentage beneath the composer, without interactive statistic dialogs or per-Turn usage. Detailed exposes session statistics and per-Turn token usage. Neither mode shows elapsed time in the completed-turn footer. The preference changes presentation only; accounting and Session events remain intact.
|
|
58
|
+
|
|
59
|
+
On non-loopback browsers, the preference remains process-local because the settings scope cannot persist writes. Explicit selections update every consumer immediately; accepted Host settings reconcile the live value on loopback browsers.
|
|
60
|
+
|
|
61
|
+
Preference menus restore focus to their trigger without scrolling before publishing a new selection.
|
|
45
62
|
|
|
46
63
|
<a id="completed-turn-footer"></a>
|
|
47
64
|
## Completed-turn footer
|
|
48
65
|
|
|
49
|
-
The
|
|
66
|
+
Artifact extensions can subscribe to one Turn and Node kind through `ChatNodeStore.turnDataSource`. The source includes hidden Nodes and exposes their business data in anchor order. Membership updates incrementally; only observed collections materialize ordered arrays, and unrelated Turns or kinds do not notify them.
|
|
67
|
+
|
|
68
|
+
The completed-turn action footer follows the recorded Turn end. Its action row starts 20px below preceding prose or extension content. Actions remain visible only on the latest Turn when its final visible content is a reply; other endings and historical Turns reveal actions on hover or keyboard focus. Devices without hover keep actions visible.
|
|
50
69
|
|
|
51
70
|
-----
|
|
52
71
|
|
|
53
72
|
<a id="turn-process-folding"></a>
|
|
54
73
|
## Turn Process Folding
|
|
55
74
|
|
|
56
|
-
|
|
75
|
+
During uninterrupted following, local steering echoes remain mounted through Inbox acceptance and claim until the durable message arrives, without triggering tail following twice. Pending inputs follow Inbox order across clients, using matching local echoes in place. After reconnect, Host-owned rows replace receipt-confirmed local echoes; a claim awaiting admission may briefly have no bubble.
|
|
57
76
|
|
|
58
|
-
|
|
77
|
+
Work-details modes control process-group display and reasoning previews; eligible completed Turns fold their process without hiding the final answer. The [business-rule reference](src/client/conversation-nodes/README.md#display-modes) contains the mode table, title behavior, whole-Turn eligibility, clocks, and disclosure resets.
|
|
78
|
+
|
|
79
|
+
-----
|
|
80
|
+
|
|
81
|
+
<a id="grouped-rendering"></a>
|
|
82
|
+
## Grouped rendering
|
|
83
|
+
|
|
84
|
+
Chat registers its process Group Definition through `uiConversation.groups`. React renders the mixed `node`/`group` root sequence through stable Group and Node seats; group headers subscribe to data separately from member arrays. Settled group titles remain independent of the live-detail preference; only running titles update when that preference changes. [Process-group business rules](src/client/conversation-nodes/README.md#process-grouping) define segmentation and activity summaries.
|
|
85
|
+
|
|
86
|
+
`groupPart` selects reasoning or response in the Assistant renderer without copying Node payloads. Each part has a distinct DOM anchor for reading-position restoration; Turn navigation addresses the original Node key and lands on its first visible part. Group sources, member parents, and keys survive display-mode changes and newly loaded prefixes that extend an intact group. The source Node Store remains the only Node-data owner, and a replaced Builder rebinds keyed subscriptions without remounting seats. Mode changes retain size observers and reuse the Turn-state selector.
|
|
87
|
+
|
|
88
|
+
The process group uses a stable `div` layout box, a scroll body, and an uncapped content box that reports growth inside the body. Business styles must adapt spacing within and across groups, including hidden or empty members and the answer-spacing exception. CSS variables do not belong in the Group Definition.
|
|
89
|
+
|
|
90
|
+
Scroll-edge fades initialize when `ResizeObserver` reports the open group's layout; opening the group performs no immediate scroll-dimension read in a layout effect.
|
|
91
|
+
|
|
92
|
+
Each group owns local `useDisclosure` state that survives mode changes while its component stays mounted.
|
|
93
|
+
|
|
94
|
+
The Chat-node slot injects a reset-bound `useDisclosure` Hook for reasoning and tools. Intermediate renderers forward it without subscribing; each invocation owns independent open state. Source callbacks retain their receiver and stable identity. When an enclosing Turn actually hides a process member, its seat resets those disclosures without replacing component keys or changing the Hook reference. Display-mode changes preserve their open state.
|
|
59
95
|
|
|
60
96
|
-----
|
|
61
97
|
|
|
62
98
|
<a id="scroll-ownership"></a>
|
|
63
99
|
## Scroll ownership
|
|
64
100
|
|
|
65
|
-
Chat restores semantic anchors across history prepend and renderer remounts. Pinned scroll deliveries without reader movement update follow ownership immediately, before subsequent layout changes can invalidate their floor.
|
|
101
|
+
Chat restores semantic anchors across history prepend and renderer remounts, with browser scroll anchoring disabled on its scrollport only while following the tail. Pinned scroll deliveries without reader movement, and reader input that reaches the exact floor, update follow ownership immediately, before subsequent layout changes can invalidate their floor. Other reader movement remains pending until the sampling interval or `scrollend`, even inside the follow threshold, so layout growth cannot erase small scroll gestures. Submitting transcript input or steering immediately restores tail following and clears an older pending reader sample. While the reader is pinned to the floor, `ResizeObserver` follows the new floor and selects the latest loaded Turn without reading row geometry. Once the reader moves away, flow-height changes preserve the top position and the reading-line geometry selects the active Turn. Turn-rail previews paint above sticky Markdown code-block banners, while the rail frame remains inside the transcript band above the composer.
|
|
102
|
+
|
|
103
|
+
The turn rail mounts only visible marks, overscan, and the focused mark's neighbors. Its fixed pitch and observed viewport size determine scroll offsets without reading the DOM scroll extent. Initial placement waits for the body's restored active Turn and the rail's first usable viewport size. The ref controls activate a Turn or scroll the rail independently; the transcript itself remains fully mounted.
|
|
104
|
+
|
|
105
|
+
While the pointer is outside the rail, automatic follow keeps the rail still when the active mark's center is inside the fade-free band and centers it after it leaves that band. Previews follow pointer movement or focus; marks scrolling under a stationary pointer do not select another preview.
|
|
106
|
+
|
|
107
|
+
<details>
|
|
108
|
+
<summary>Scroll implementation — click to expand</summary>
|
|
109
|
+
|
|
110
|
+
`useChatViewport` owns turn-aware DOM reads, clamped writes, native events, and one retained paging anchor. For Load older, Node and Group seats mark eligible anchors from their existing disclosure state. The viewport selects the first nonempty, unhidden marker in transcript order without hit testing or geometry-based search, then measures that element and its scroll containers. It compensates the anchor's capped group first, then gives the remaining displacement to the transcript scrollport. Commits and later content resizes reuse that anchor; a remounted row is resolved by the same semantic key. Compensation stays within the actual scroll ranges without adding bottom space.
|
|
111
|
+
|
|
112
|
+
`useChatReading` owns follow policy, sampled reader input, and semantic memory; `useChatNavigation` owns turn jumps and requests preservation from the viewport. Reading gestures release the paging anchor, but composer clicks, typing, and non-scrolling keys retain it; while a page is still loading, `scrollend` captures the reader's new position. `useChatScroll` coordinates their committed inputs. Explicit navigation carries its measured landing into reading policy, so it does not rediscover the known target with a hit test.
|
|
113
|
+
|
|
114
|
+
Active-Turn highlighting is approximate: `readVisibleTurn` binary-searches the content column's direct Node/Group boxes and retains the preceding candidate in gaps. It neither hit-tests the document nor searches Group members or all Turn markers. Empty Seats retain zero-height in-flow boxes so outer positions remain ordered without extra spacing. This lookup does not change semantic position capture or paging compensation.
|
|
115
|
+
|
|
116
|
+
</details>
|
|
66
117
|
|
|
67
118
|
-----
|
|
68
119
|
|
|
@@ -79,6 +130,9 @@ None; Chat presentation does not assemble or mutate provider requests.
|
|
|
79
130
|
|
|
80
131
|
<a id="known-limitations-and-deferred-work"></a>
|
|
81
132
|
|
|
133
|
+
|
|
134
|
+
- **Developer messages are not displayed** — presentation is intentionally deferred; encountering `developer/message` throws instead of rendering a fallback row.
|
|
135
|
+
|
|
82
136
|
- **The transcript reflects the loaded Session window** — older transcript nodes become available only after Session Controller loads the preceding event page. Turn navigation is wider than the window: the rail merges the loaded Turns with the host `turnOutline` projection, so every started Turn gets a fixed-pitch mark (10px apart; a ladder taller than the frame scrolls inside it with gradient fades), and activating an unloaded mark pages history through the Turn's `turn/start` seq before landing on its row. Without the projection (assemblies not mounting `dsh-session-turn-outline`) the rail falls back to loaded Turns only.
|
|
83
137
|
- **Rail previews are card-sized** — one prompt line (50 characters) and up to three response lines (120), on loaded and unloaded Turns alike; an unloaded Turn's response arrives from the outline only once the Turn settled, so an open Turn previews its prompt (or just the Turn number) until then.
|
|
84
138
|
|
package/README.zh.md
CHANGED
|
@@ -8,17 +8,19 @@ kind: "package-reference"
|
|
|
8
8
|
|
|
9
9
|
## 概述
|
|
10
10
|
|
|
11
|
-
使用本包可在浏览器中渲染已记录的 Session
|
|
11
|
+
使用本包可在浏览器中渲染已记录的 Session 对话,包括历史图片、本地化操作和滚动位置恢复。工作过程展示模式控制思考预览,并收起符合条件的已完成轮次过程行,不隐藏最终答案。本地 transcript(文本记录)与 steering(中途引导)提交会立即显示并保留在原区域,在权威会话记录到达时原子地消失,而排队中的提交始终不进入 Chat。本包不组装或修改模型请求。
|
|
12
12
|
|
|
13
13
|
文件提及提供方同时接收当前查看的会话 ID 与收尾轮次的属主信息,因此继承历史中的链接可以指向 fork 自身。
|
|
14
14
|
|
|
15
15
|
## 目录
|
|
16
16
|
|
|
17
17
|
- [引用预览](#reference-previews)
|
|
18
|
-
- [
|
|
18
|
+
- [Chat 隐藏的行](#system-prompt-row)
|
|
19
|
+
- [指令与失败行](#command-and-failure-rows)
|
|
19
20
|
- [轮次 token 用量](#turn-token-usage)
|
|
20
21
|
- [已完成轮次的页脚](#completed-turn-footer)
|
|
21
22
|
- [轮次过程折叠](#turn-process-folding)
|
|
23
|
+
- [分组渲染](#grouped-rendering)
|
|
22
24
|
- [滚动归属](#scroll-ownership)
|
|
23
25
|
- [模型体验](#model-experience)
|
|
24
26
|
- [已知限制与暂缓事项](#known-limitations-and-deferred-work)
|
|
@@ -29,12 +31,21 @@ kind: "package-reference"
|
|
|
29
31
|
<a id="reference-previews"></a>
|
|
30
32
|
## 引用预览
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
Chat 在节点列表外通过一个 `MarkdownDelegateProvider` 提供文件及 HTTP(S) 导航。Assistant Markdown 文件链接在消息落定后可于右侧栏打开,包括未修改文件的引用。相对路径基于当前查看的 Session 工作区解析;绝对路径仍使用同一 Session 的文件系统访问。`#L24` 和 `#L24-L30` 定位到指定起始行,并复用现有文件标签。文件缺失时显示预览错误状态。
|
|
35
|
+
|
|
36
|
+
设置 → 通用设置 → 聊天链接打开方式控制普通点击 Chat HTTP(S) 链接时的目标:「内置浏览器」(默认)打开新的右侧 Sidebar Browser tab,「浏览器新标签页」打开外部标签页。该设置项仅在内置浏览器可用时显示。若 Sidebar Browser 未注册,两种选择均使用外部浏览器;带修饰键的点击保留原生行为。`ui-chat.linkOpening` 偏好在回环地址浏览器中持久化,设置无法持久化写入时仅在当前进程内生效。已发送的文件引用及消息日志确认调用的 skill 也可在右侧栏打开预览。文件路径使用当前查看的 Session;skill 名称由该 Session 当前的输入触发源解析。两者悬停或聚焦时均使用正文文件链接的虚线下划线。会话、目录和命令标签仍只作为引用展示。
|
|
33
37
|
|
|
34
38
|
<a id="system-prompt-row"></a>
|
|
35
|
-
##
|
|
39
|
+
## Chat 隐藏的行
|
|
40
|
+
|
|
41
|
+
Chat 在所有工作过程展示模式下都不显示系统提示词行、普通上下文注入和 `permission` 命令行。该过滤不改变已记录的 Session 事件或 Trajectory 查看能力。非人工轮次触发仍作为独立通知显示,其他命令行仍保留在 Chat 中。
|
|
42
|
+
|
|
43
|
+
Assistant 尝试结束且没有可见消息时,Chat 隐藏已发布的 Node,不移除其 key。同一 Step 的重试再次产生可见内容时,复用该 key。已加载窗口缺少 Step 起点时也遵循此规则。
|
|
44
|
+
|
|
45
|
+
<a id="command-and-failure-rows"></a>
|
|
46
|
+
## 指令与失败行
|
|
36
47
|
|
|
37
|
-
|
|
48
|
+
通用指令行在所有生命周期状态中都保留普通指令图标;失败仍通过行状态与摘要明确表达。终止轮次的错误仍是独立的红点提示;模型的中间重试不会创建该提示,达到输出 token 上限时使用琥珀色警告点。
|
|
38
49
|
|
|
39
50
|
-----
|
|
40
51
|
|
|
@@ -43,28 +54,66 @@ kind: "package-reference"
|
|
|
43
54
|
|
|
44
55
|
只有当已加载窗口包含 `turn/start`,且每次已启动的模型尝试都报告安全、精确的用量时,已完成轮次才显示可展开的用量行。该行会省略不可用的可选用量桶。记账不完整或相互矛盾时,整个详情都不显示,避免把部分总量冒充完整结果。
|
|
45
56
|
|
|
46
|
-
|
|
57
|
+
设置 → 通用设置 → 性能与用量将 `ui-chat.performanceUsage` 保存为 `detailed`(默认)或 `compact`。简洁模式仅在输入框下方显示可用的输出速度和缓存命中率,不显示统计交互卡片或每轮用量。详细模式提供会话统计和每轮 token 用量。两种模式的已完成轮次页脚均不显示耗时。该偏好仅影响展示,记账和 Session 事件保持完整。
|
|
58
|
+
|
|
59
|
+
在非回环地址浏览器中,设置作用域无法持久化写入,因此该偏好仅在当前进程内生效。明确选择会立即更新所有使用方;回环地址浏览器收到 Host 已接受的设置后会同步当前值。
|
|
60
|
+
|
|
61
|
+
偏好菜单在发布新选择之前,先将焦点还给触发按钮,且不引起滚动。
|
|
47
62
|
|
|
48
63
|
<a id="completed-turn-footer"></a>
|
|
49
64
|
## 已完成轮次的页脚
|
|
50
65
|
|
|
51
|
-
|
|
66
|
+
产物扩展可通过 `ChatNodeStore.turnDataSource` 订阅一个 Turn 中指定类型的节点数据。来源包含隐藏节点,并按锚点顺序提供其业务数据。成员关系增量更新;只有被订阅的集合才生成有序数组,其他 Turn 或类型的更新不通知该集合。
|
|
67
|
+
|
|
68
|
+
已完成轮次的操作页脚位于记录的轮次结束之后。操作行与前方正文或扩展内容相隔 20px。只有最新轮次且最后可见内容为回复时,操作常显;其他结尾及历史轮次在悬停或键盘聚焦时显示操作。不支持悬停的设备始终显示操作。
|
|
52
69
|
|
|
53
70
|
-----
|
|
54
71
|
|
|
55
72
|
<a id="turn-process-folding"></a>
|
|
56
73
|
## 轮次过程折叠
|
|
57
74
|
|
|
58
|
-
|
|
75
|
+
正常在线时,本地 steering 回显在 Inbox 接受与领取期间保持挂载,直到持久消息到达,不会重复触发跟随底部。跨客户端的待处理输入遵循 Inbox 顺序,在匹配位置使用本地回显。重连后,Host 消息替代已有接收回执的本地回显;已领取但尚未入档时,气泡可能短暂消失。
|
|
59
76
|
|
|
60
|
-
|
|
77
|
+
工作过程展示模式控制过程组显示与推理预览;符合条件的已完成轮次折叠过程,但不隐藏最终答案。[业务规则明细](src/client/conversation-nodes/README.zh.md#display-modes) 统一说明模式表、组头行为、整轮折叠资格、时钟与开合重置。
|
|
78
|
+
|
|
79
|
+
-----
|
|
80
|
+
|
|
81
|
+
<a id="grouped-rendering"></a>
|
|
82
|
+
## 分组渲染
|
|
83
|
+
|
|
84
|
+
Chat 通过 `uiConversation.groups` 注册过程 Group Definition。React 通过稳定的 Group 与 Node 容器渲染混合 `node`/`group` 根序列,组头数据与成员数组分别订阅。已结束组的标题独立于实时详情偏好,只有运行中的标题在该偏好变化时更新。[过程分组业务规则](src/client/conversation-nodes/README.zh.md#process-grouping) 定义切分方式与活动摘要。
|
|
85
|
+
|
|
86
|
+
`groupPart` 在 Assistant 渲染器中选择推理或回复,不复制 Node 载荷。每个部分有独立的 DOM 锚点用于恢复阅读位置;轮次导航使用原 Node key,落到它的第一个可见部分。展示模式切换以及为完整旧组补入更早成员时,保留组来源、成员父级及 key。原 Node Store 仍是唯一节点数据所有者,替换 Builder 时重新绑定按键订阅,不重挂载容器。模式变化保留尺寸观察器,并复用整轮状态选择器。
|
|
87
|
+
|
|
88
|
+
过程组使用稳定的 `div` 布局盒子、滚动正文及不限高的内容盒子,后者报告正文内部的内容增长。业务样式必须适配组内及组边界间距,处理隐藏或空成员以及回答前的间距特例。CSS 变量不属于 Group Definition。
|
|
89
|
+
|
|
90
|
+
滚动边缘渐隐在 `ResizeObserver` 报告已展开组的布局后初始化;展开组时不会在 layout effect 中立即读取滚动尺寸。
|
|
91
|
+
|
|
92
|
+
每个组拥有本地 `useDisclosure` 状态,组件保持挂载时,模式切换保留该状态。
|
|
93
|
+
|
|
94
|
+
Chat 节点 slot 为推理与工具注入绑定重置来源的 `useDisclosure` 钩子。中间 renderer 只透传、不订阅,每次调用拥有独立展开状态。来源回调保留接收对象及稳定引用。外层轮次实际隐藏过程成员时,所在节点重置这些开合状态,不替换组件 key,也不改变钩子引用。展示模式切换保留展开状态。
|
|
61
95
|
|
|
62
96
|
-----
|
|
63
97
|
|
|
64
98
|
<a id="scroll-ownership"></a>
|
|
65
99
|
## 滚动归属
|
|
66
100
|
|
|
67
|
-
Chat 会在历史前插与 renderer
|
|
101
|
+
Chat 会在历史前插与 renderer 重新挂载时恢复语义锚点,并且只在跟随底部时禁用自己滚动区域的浏览器自动锚定。没有读者移动的贴底滚动事件,以及确实到达最底部的读者输入,会立即更新跟随归属,避免后续布局变化使其底部位置失效。其他读者移动即使位于跟随阈值内,也保持待处理直到采样周期或 `scrollend`,防止布局增长抵消小幅滚动操作。提交正文输入或 steering 时立即恢复跟随底部,并清除先前待处理的读者滚动采样。读者跟随底部时,`ResizeObserver` 追随新的底部,并且无需读取行几何就选中最后一个已加载轮次;读者离开底部后,高度变化会保持顶部位置,再由阅读线几何选择活跃轮次。轮次导航预览位于 Markdown 代码块粘性头栏上方,而导航外框始终处于 composer 上方的 transcript 区域内。
|
|
102
|
+
|
|
103
|
+
轮次轨道只挂载可见刻度、预加载范围及键盘焦点刻度的相邻项。固定间距和观察到的视口尺寸决定滚动偏移,不读取 DOM 滚动总高度。初始定位等待正文恢复活跃轮次,以及轨道首次获得可用视口尺寸。ref 控制接口分别支持激活轮次和仅滚动轨道;正文自身仍完整挂载。
|
|
104
|
+
|
|
105
|
+
指针位于轨道外时,自动跟随在活跃刻度中心处于非渐隐区域内时保持轨道不动,越界后才将其居中。预览随指针移动或焦点切换;刻度在静止指针下滚动不会选中另一个预览。
|
|
106
|
+
|
|
107
|
+
<details>
|
|
108
|
+
<summary>滚动实现——点击展开</summary>
|
|
109
|
+
|
|
110
|
+
`useChatViewport` 负责识别轮次的 DOM 读取、限制范围后的写入、原生事件及一个持续保留的分页锚点。加载更早时,Node 与 Group 容器根据已有开合状态标记可选锚点。视口按正文顺序选择第一个非空、未隐藏的标记,不做命中测试或按几何位置搜索,再测量该元素及其滚动容器。先补偿锚点所在的限高组,再把剩余位移交给整段文本的滚动区域。提交和后续内容尺寸变化复用该锚点;消息行重挂载时按同一语义 key 重新定位。补偿限于实际可滚动范围,不增加底部空白。
|
|
111
|
+
|
|
112
|
+
`useChatReading` 负责跟随策略、读者输入采样和语义位置记忆;`useChatNavigation` 负责轮次跳转,并向视口请求位置保持。阅读手势释放分页锚点,composer 内的点击、打字和非滚动按键则保留锚点;分页仍在加载时,`scrollend` 会记录读者的新位置。`useChatScroll` 协调已提交的输入。显式导航把测得的落点交给阅读策略,因此无需通过命中测试重新寻找已知目标。
|
|
113
|
+
|
|
114
|
+
活跃轮次高亮采用近似定位:`readVisibleTurn` 对正文容器的直属 Node/Group 布局盒二分,落在间隙时保留前方候选。它不做文档命中测试,也不查询 Group 成员或全部 Turn 标记。空 Seat 保留零高度的流内布局盒,使外层位置有序且不增加间距。这种定位不改变语义位置捕获或分页补偿。
|
|
115
|
+
|
|
116
|
+
</details>
|
|
68
117
|
|
|
69
118
|
-----
|
|
70
119
|
|
|
@@ -81,6 +130,9 @@ Chat 会在历史前插与 renderer 重新挂载时恢复语义锚点。没有
|
|
|
81
130
|
|
|
82
131
|
<a id="known-limitations-and-deferred-work"></a>
|
|
83
132
|
|
|
133
|
+
|
|
134
|
+
- **不展示 developer 消息** — 展示能力有意留待后续实现;遇到 `developer/message` 时抛出错误,不渲染回退行。
|
|
135
|
+
|
|
84
136
|
- **transcript 只反映已加载的 Session 窗口**——只有会话控制器加载前一页事件后,更早的 transcript node 才会出现。轮次导航比窗口更宽:轨道把已加载的轮次与宿主 `turnOutline` 投影合并,每个已开始的轮次都有固定间距刻度(相隔 10px;阶梯高于外框时在框内滚动并以渐变淡出标示可滚方向),激活未加载刻度会先把历史分页拉到该轮次的 `turn/start` seq 再落到它的行上。没有该投影时(未挂载 `dsh-session-turn-outline` 的装配),轨道回退到仅显示已加载轮次。
|
|
85
137
|
- **导航预览按卡片尺寸截断**——提示词一行(50 字符)、回复至多三行(120 字符),已加载与未加载 Turn 一致;未加载 Turn 的回复要等该轮落定后才随大纲到达,进行中的轮次在此之前只预览提示词(或仅轮次号)。
|
|
86
138
|
|