@deepseek-ai/dsh-client-ui-conversation 0.1.7-alpha.1 → 0.1.7-rc.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 +3 -3
- package/README.zh.md +3 -3
- package/lib/client.js +111 -68
- package/lib/types/client/contract/conversation.d.ts +6 -6
- package/lib/types/client/contract/records.d.ts +15 -5
- package/lib/types/client/conversation/assembler.d.ts +3 -0
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/locales.d.ts +4 -4
- package/lib/types/client/queue/QueueDock.d.ts +1 -1
- package/package.json +35 -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-conversation/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 153c505250f5654f0aeade23c221e19554294641
|
|
6
|
+
README.zh.md: c849b1bdfd033e07cac382c4b62cd0df35333c8e
|
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ English | [中文](README.zh.md)
|
|
|
27
27
|
|
|
28
28
|
`UiConversation.events` is the single registry for event Definitions, and `UiConversation.views` is the single registry for target snapshot builders. Both registries reject duplicate keys, preserve registration order, return idempotent disposers, and rebuild existing bindings when their contribution roster changes. `UiConversation.binding(bindingOrSessionId)` returns one identity-stable Conversation binding for the current Session Controller binding. It does not open another event source. A View Definition may declare `toolCallFocus` to translate a tool-call id into its focus identity. Conversation supplies an Inspect callback only while such a target has a visible View entry; Chat consumes this callback without selecting a target.
|
|
29
29
|
|
|
30
|
-
The adapter passes each `SessionEventLikeEntry` directly to the assembler. Its outer `type` distinguishes durable events from Client-only transient events, while its inner `event` always exposes `type`, `seq`, `time`, and `data`; Definitions receive that inner `SessionEventLike`. Replacement windows may include both entry variants, while historical prepends carry durable entries and live appends may carry either.
|
|
30
|
+
The adapter passes each `SessionEventLikeEntry` directly to the assembler. Its outer `type` distinguishes durable events from Client-only transient events, while its inner `event` always exposes `type`, `seq`, `time`, and `data`; Definitions receive that inner `SessionEventLike`. Replacement windows may include both entry variants, while historical prepends carry durable entries and live appends may carry either. Definitions use the same match/start/update interface for durable and transient events. The earliest loaded start initializes State; every later Match, including another start for that identity, updates it. Definitions that do not consume Assistant deltas return `null` for `assistant/live-chunk`. Replacement windows and revision gaps rebuild from the complete loaded window; contiguous append, prepend, and Assistant-settlement revisions use incremental assembly. Settlement removes only the named attempt's transient matches, applies its optional durable entry, and recomputes the affected Contexts from their remaining earliest start, refreshing predecessor indexes and dependents without replacing unrelated target nodes. A Context with no remaining start has no State. Its key and previously published nodes remain available to later evidence until a full window rebuild; the owning Definition may hide those nodes. The assembler owns Context matching, Turn/Step locations, target node materialization, target activity, and stable target sources. `ConversationSnapshot` contains only target-neutral views and active-target facts; Session lifecycle state remains in `SessionSnapshot`.
|
|
31
31
|
|
|
32
32
|
A target becomes active when shell selection resolves it or when its source receives a first subscriber. The assembler replaces that target from current Contexts once and keeps it active for later incremental flushes; creating a source does not activate it and unsubscription does not deactivate it.
|
|
33
33
|
|
|
@@ -68,9 +68,9 @@ Active transcripts in the main occurrence expose content-width drag handles in t
|
|
|
68
68
|
|
|
69
69
|
The width-handle indicator follows the pointer only during a captured drag; ordinary hover leaves its position unchanged.
|
|
70
70
|
|
|
71
|
-
The resident composer survives no-Session and Session transitions. Whitespace hides its placeholder; a whitespace-only draft without attachments cannot be sent. The no-Session state keeps the same composer surface mounted but inert while the Workspace picker connects a blank Session. The surface is a shell-owned Lexical editor: reference chips are atomic decorator nodes carrying the owner's serialization identity (submission expands them through the owner codec), claimed slash commands stay styled leading text, folder text references carry the folder glyph as an icon prefix, and the draft's clipboard projection is mirrored into the per-Session Conversation store. QueueDock reads `next-turn`
|
|
71
|
+
The resident composer survives no-Session and Session transitions. Whitespace hides its placeholder; a whitespace-only draft without attachments cannot be sent. The no-Session state keeps the same composer surface mounted but inert while the Workspace picker connects a blank Session. The surface is a shell-owned Lexical editor: reference chips are atomic decorator nodes carrying the owner's serialization identity (submission expands them through the owner codec), claimed slash commands stay styled leading text, folder text references carry the folder glyph as an icon prefix, and the draft's clipboard projection is mirrored into the per-Session Conversation store. QueueDock reads `next-turn` from the Session `inbox` projection, including cold recovered messages, and excludes only requestIds still owned by local transcript submissions. Other queued rows retain their normal display and actions. Queue operations address exact queue occurrences through the scoped `ctx.conversation` service; queue previews render sent text through the shared inline reference projection from `ui-primitives` (wire session forms fold to their label) and show local or durable images and files in original attachment order. Images use thumbnails; files use compact name-and-size cards. An edit exposes the literal sent text in a textarea that grows with its content, so line breaks survive re-editing; Enter saves, Shift+Enter breaks the line, and Escape cancels. Durable thumbnails resolve through the session image URL cache. Busy Enter behavior is stored in the Host-backed `ui-conversation` settings namespace. The composer keymap arbitrates the trigger menu's keys through the slash pipeline — Tab settles the highlighted completion (or drills a drillable one), Escape and Shift+Tab leave the menu without settling — and leaves every other key to the editor. An overlay that takes the keyboard hands it back through `SessionInput.focus()`, which rides Lexical's own focus so the caret returns where the draft left it rather than at the start.
|
|
72
72
|
|
|
73
|
-
Default sends commit optimistically: Enter clears the draft, occurrence table, and undo history in the same transaction, keeps the composer in `plain`, and runs the send as a detached attempt, so typing and further sends continue during the flight. `sendSession` registers a Session submission echo (`session.beginSubmission`) with the delivery mode before serializing, preserving selected image and file order in `pendingSubmissions`; Session derives the placement from that mode and its current running state, so idle sends use the transcript, busy Queue sends use QueueDock, and busy Steer sends use the pending-steering surface. It then yields one paint, encodes images through the browser's native `FileReader` data-URL path, and cites staged file receipts. Command submissions use the same receipts for generic files, so sending `/goal` or `/plan` never reads those browser files again. The prompt reuses the submission `requestId`;
|
|
73
|
+
Default sends commit optimistically: Enter clears the draft, occurrence table, and undo history in the same transaction, keeps the composer in `plain`, and runs the send as a detached attempt, so typing and further sends continue during the flight. `sendSession` registers a Session submission echo (`session.beginSubmission`) with the delivery mode before serializing, preserving selected image and file order in `pendingSubmissions`; Session derives the placement from that mode and its current running state, so idle sends use the transcript, busy Queue sends use QueueDock, and busy Steer sends use the pending-steering surface. It then yields one paint, encodes images through the browser's native `FileReader` data-URL path, and cites staged file receipts. Command submissions use the same receipts for generic files, so sending `/goal` or `/plan` never reads those browser files again. The prompt reuses the submission `requestId`; Session retires the echo once at its display handoff, correlated by that `rpcId`. Concurrent failures are restored together in submission order until the user edits the restored content; command submissions keep the frozen `submitting` phase. Detached attempts retain their attachment ids through admission and Session scope disposal. An observed retirement immediately exposes each image preview through the durable cache, replaces it with the canonical URL after fetching the admitted attachment, revokes each URL after its use ends, and releases file cards. Selected generic files enter one FIFO background-upload queue; `maxConcurrentFileUploads` defaults to two active Worker transports, the Conversation service retains queued and active operations plus byte progress across Session navigation, and removing a draft skips its queued transfer or aborts its active transport. Where the browser shell exposes `__DSH_HOST_PATHS__` (the Desktop application), dropped or pasted folders and dropped, picked, or pasted non-image files with a real path become `@path` chips; images keep uploading. Drag-and-drop and paste identify directories through the browser entry API; when that API is absent or returns no entry, pasted items retain ordinary file handling. The file picker cannot select directories. References require the `ui-reference` plugin and the original paths to remain readable by the model's file tools. Paths inside the workspace are relative; others remain absolute. The whole batch is validated before insertion, retains source order and selected text, and uses whitespace-separated, closed-quote mentions. A browser without the bridge refuses dropped or pasted folders; a Desktop folder without a reported path is rejected separately. Continuable subagents disable attachment intake and skip local echoes because their transport does not preserve the browser request id.
|
|
74
74
|
|
|
75
75
|
Queued submission echoes show “Sending…” beside disabled edit, remove, and steer buttons; a collapsed dock keeps the sending status in its header. A matching Host queue row replaces the echo and enables each action according to its normal text-content and running-state requirements. Prompt acknowledgement alone does not enable queue actions. A failed submission removes its echo and displays an error; the composer restores the failed draft when it is empty or still contains the previous automatic restoration, preserving subsequently typed text.
|
|
76
76
|
|
package/README.zh.md
CHANGED
|
@@ -27,7 +27,7 @@ kind: "package-reference"
|
|
|
27
27
|
|
|
28
28
|
`UiConversation.events` 是 event Definition 的唯一 registry,`UiConversation.views` 是 target snapshot builder 的唯一 registry。两者都拒绝重复 key、保持注册顺序、返回幂等 disposer,并在 contribution roster 变化时重建现有 binding。`UiConversation.binding(bindingOrSessionId)` 为当前 Session Controller binding 返回 identity 稳定的 Conversation binding,不会另开事件源。 View Definition 可以声明 `toolCallFocus`,将工具调用 id 转换为自身的焦点标识。仅当此目标拥有可见的 View 条目时,Conversation 才提供 Inspect 回调;Chat 直接使用回调,不选择目标。
|
|
29
29
|
|
|
30
|
-
适配器把每个 `SessionEventLikeEntry` 直接交给 assembler。外层 `type` 区分持久事件与 Client-only transient event,内部 `event` 则统一公开 `type`、`seq`、`time` 与 `data`;Definition 接收这个内部 `SessionEventLike`。replacement window 可以包含两种 entry,历史 prepend 携带持久 entry,实时 append
|
|
30
|
+
适配器把每个 `SessionEventLikeEntry` 直接交给 assembler。外层 `type` 区分持久事件与 Client-only transient event,内部 `event` 则统一公开 `type`、`seq`、`time` 与 `data`;Definition 接收这个内部 `SessionEventLike`。replacement window 可以包含两种 entry,历史 prepend 携带持久 entry,实时 append 则可以携带任一种。持久与瞬态事件使用同一组 match/start/update 接口。当前最早的 start 初始化 State;后续所有 Match,包括同一身份的其他 start,都用于更新。不消费 Assistant delta 的 Definition 对 `assistant/live-chunk` 返回 `null`。replace window 或 revision 断档从完整已加载窗口重建;连续 revision 的 append、prepend 与 Assistant settlement 使用增量组装。settlement 只删除具名 attempt 的 transient match,应用可选持久 entry,并从剩余最早的 start 重算受影响的 Context,刷新前序索引及 dependent,不替换无关 target node。没有剩余 start 的 Context 不保留 State,但其 key 和已发布节点仍保留,供后续证据复用,直到完整窗口重建;所属 Definition 可以隐藏这些节点。assembler 拥有 Context 匹配、Turn/Step location、target node 物化、target activity 和稳定 target source。`ConversationSnapshot` 只包含与 target 无关的 View 与 active-target 事实;Session lifecycle 状态仍属于 `SessionSnapshot`。
|
|
31
31
|
|
|
32
32
|
shell 选择解析出 target 或 target source 收到首个 subscriber 时,该 target 进入 active 状态。assembler 从当前 Context 对它执行一次 replace,并使它参与后续增量 flush;创建 source 不会激活 target,取消订阅也不会停用 target。
|
|
33
33
|
|
|
@@ -68,9 +68,9 @@ Session 首次绑定或缓存的 Session 成为 current 时,shell 会在渲染
|
|
|
68
68
|
|
|
69
69
|
宽度拖拽条的指示线只在已捕获指针的拖拽期间跟随指针,普通悬停不改变其位置。
|
|
70
70
|
|
|
71
|
-
常驻 composer 在无 Session 与有 Session 之间保持挂载。输入空白字符会隐藏占位提示;没有附件的纯空白草稿无法发送。无 Session 时,同一个编辑器表面保持 inert,Workspace picker 连接 blank Session。该表面是 shell 所有的 Lexical 编辑器:引用 chip 是携带 owner 序列化身份的原子 decorator 节点(提交时经 owner codec 展开),已认领的 slash command 保持为带样式的行首文本,文件夹文本引用以图标前缀携带文件夹图形,草稿的剪贴板投影镜像到逐 Session Conversation store。QueueDock
|
|
71
|
+
常驻 composer 在无 Session 与有 Session 之间保持挂载。输入空白字符会隐藏占位提示;没有附件的纯空白草稿无法发送。无 Session 时,同一个编辑器表面保持 inert,Workspace picker 连接 blank Session。该表面是 shell 所有的 Lexical 编辑器:引用 chip 是携带 owner 序列化身份的原子 decorator 节点(提交时经 owner codec 展开),已认领的 slash command 保持为带样式的行首文本,文件夹文本引用以图标前缀携带文件夹图形,草稿的剪贴板投影镜像到逐 Session Conversation store。QueueDock 从 Session 的 `inbox` 投影读取 `next-turn`,包含从冷状态恢复的消息,仅排除仍由本地 transcript 提交承接的 requestId。其他排队行保留正常展示和操作。Queue 操作通过 scoped `ctx.conversation` service 寻址准确的 queue occurrence;queue 预览经 `ui-primitives` 的共享行内引用投影渲染已发送文本(wire 会话形式折叠为其标签),并按原始附件顺序展示本地或持久化的图片和文件。图片使用缩略图,文件使用紧凑的名称与大小卡片。编辑态在可随内容增高的 textarea 中展示字面发送文本,因此重新编辑不会丢失换行;Enter 保存,Shift+Enter 换行,Escape 取消。持久化缩略图通过会话图片 URL 缓存解析。繁忙时 Enter 行为保存在 Host-backed `ui-conversation` settings namespace。 composer 键盘映射经斜杠流水线裁决触发菜单的按键——Tab 确认高亮补全项(可下钻项则下钻),Escape 与 Shift+Tab 离开菜单且不选定——其余按键交给编辑器自身。 接管键盘的浮层通过 `SessionInput.focus()` 把键盘还回来,该路径走 Lexical 自己的 focus,因此光标回到草稿原来的位置而不是开头。
|
|
72
72
|
|
|
73
|
-
默认发送采用乐观提交:Enter 在同一事务里清空草稿、occurrence 表和撤销历史,composer 保持 `plain`,发送作为 detached attempt 运行,发送期间可以继续输入和提交。`sendSession` 在序列化之前用投递模式注册 Session 提交回显(`session.beginSubmission`),并在 `pendingSubmissions` 中保留图片与文件的选择顺序;Session 根据该模式与当前运行状态推导位置,因此空闲发送进入 transcript(文本记录),繁忙时 Queue 进入 QueueDock,繁忙时 Steer 进入 pending-steering 区域。随后让出一帧,图片经浏览器原生 `FileReader` data-URL 路径编码,文件则引用已暂存凭证。命令提交也用同一凭证表示通用文件,因此发送 `/goal` 或 `/plan` 时不会再次读取这些浏览器文件。提示词复用提交 `requestId`;
|
|
73
|
+
默认发送采用乐观提交:Enter 在同一事务里清空草稿、occurrence 表和撤销历史,composer 保持 `plain`,发送作为 detached attempt 运行,发送期间可以继续输入和提交。`sendSession` 在序列化之前用投递模式注册 Session 提交回显(`session.beginSubmission`),并在 `pendingSubmissions` 中保留图片与文件的选择顺序;Session 根据该模式与当前运行状态推导位置,因此空闲发送进入 transcript(文本记录),繁忙时 Queue 进入 QueueDock,繁忙时 Steer 进入 pending-steering 区域。随后让出一帧,图片经浏览器原生 `FileReader` data-URL 路径编码,文件则引用已暂存凭证。命令提交也用同一凭证表示通用文件,因此发送 `/goal` 或 `/plan` 时不会再次读取这些浏览器文件。提示词复用提交 `requestId`;Session 按同一 `rpcId` 关联展示接管,并仅退休回显一次。多个并发发送失败时,在用户编辑还原内容之前按提交顺序合并还原;命令提交保持冻结的 `submitting` 阶段。Detached attempt 持有附件 id,直到 admission 完成或 Session scope 销毁。回显以 observed 退休时,durable 图片缓存立即公开每个预览 URL,读取 admitted 附件后用规范化 URL 替换预览,并在各 URL 停止使用后撤销,同时释放文件卡。选中的通用文件进入同一个先进先出的后台上传队列;`maxConcurrentFileUploads` 默认允许两个 Worker transport 同时运行,Conversation 服务在切换 Session 时继续持有排队和运行中的传输操作及字节进度,移除草稿会跳过排队中的传输或中止正在运行的传输。浏览器 shell 暴露 `__DSH_HOST_PATHS__` 时(桌面应用),拖入或粘贴的文件夹以及拖入、选择或粘贴的带真实路径的非图片文件会成为 `@路径` chip;图片仍然上传。拖放和粘贴通过浏览器 entry API 识别目录;该 API 不可用或没有返回 entry 时,粘贴项沿用普通文件处理。文件选择器不能选择目录。引用需要启用 `ui-reference` 插件,原路径也必须仍可由模型的文件工具读取。工作区内的路径使用相对形式,其他路径保留绝对形式。整批文件先校验再插入,保留来源顺序和已选中的文字,引用之间有空白分隔,含空格的路径使用闭合引号。没有该桥的浏览器会拒绝拖入或粘贴的文件夹,桌面端无法获取文件夹路径时单独报错。continuable 子代理禁用附件入口,也不创建本地回显,因为其 transport 不保留浏览器 request id。
|
|
74
74
|
|
|
75
75
|
排队提交的本地回显在禁用的编辑、删除、插话按钮旁显示“发送中…”;折叠后的队列在标题栏保留发送状态。匹配的 Host 队列行替换回显后,各操作按原有的纯文本内容和运行状态要求启用。仅收到提示词确认不会启用队列操作。提交失败会移除回显并显示错误;输入框为空或仍保留上一次自动恢复的内容时,composer 恢复失败草稿,保留用户随后输入的文字。
|
|
76
76
|
|
package/lib/client.js
CHANGED
|
@@ -1860,15 +1860,7 @@ window.__ModuleLoader__.load({
|
|
|
1860
1860
|
}
|
|
1861
1861
|
return merged;
|
|
1862
1862
|
}
|
|
1863
|
-
function conversationMatch(
|
|
1864
|
-
if (role === "start") {
|
|
1865
|
-
if (input.type !== "event") throw new Error(`conversation Context ${key} received a transient start Match`);
|
|
1866
|
-
return {
|
|
1867
|
-
event: input.event,
|
|
1868
|
-
role,
|
|
1869
|
-
location
|
|
1870
|
-
};
|
|
1871
|
-
}
|
|
1863
|
+
function conversationMatch(input, role, location) {
|
|
1872
1864
|
return {
|
|
1873
1865
|
event: input.event,
|
|
1874
1866
|
role,
|
|
@@ -1971,6 +1963,8 @@ window.__ModuleLoader__.load({
|
|
|
1971
1963
|
}
|
|
1972
1964
|
/**
|
|
1973
1965
|
* Retire one Assistant attempt's transient matches and apply its optional durable settlement.
|
|
1966
|
+
* Empty Contexts retain their keys and published nodes until the loaded window is rebuilt;
|
|
1967
|
+
* Definitions may hide those nodes when no start remains instead of withdrawing their identities.
|
|
1974
1968
|
* @param attemptId - process-local attempt whose transient presentation ended.
|
|
1975
1969
|
* @param entry - durable message or attempt event committed for the stream.
|
|
1976
1970
|
* @returns highest requested publication cadence.
|
|
@@ -2126,7 +2120,7 @@ window.__ModuleLoader__.load({
|
|
|
2126
2120
|
collectInput(input, pending) {
|
|
2127
2121
|
return this.dispatchInput(input, (definition, id, role) => {
|
|
2128
2122
|
const key = conversationContextKey(definition.kind, id);
|
|
2129
|
-
const match = conversationMatch(
|
|
2123
|
+
const match = conversationMatch(input, role, this.locationIndex.locationOf(input.event));
|
|
2130
2124
|
const matches = pending.get(key) ?? [];
|
|
2131
2125
|
matches.push({
|
|
2132
2126
|
definition,
|
|
@@ -2177,14 +2171,14 @@ window.__ModuleLoader__.load({
|
|
|
2177
2171
|
acceptMatch(definition, id, role, input) {
|
|
2178
2172
|
const key = conversationContextKey(definition.kind, id);
|
|
2179
2173
|
let context = this.contexts.get(key);
|
|
2180
|
-
if (role === "start" && context?.start !== void 0) throw new Error(`conversation Context ${key} received more than one start Match`);
|
|
2181
2174
|
context ??= this.createContext(definition, id, key);
|
|
2182
|
-
const
|
|
2175
|
+
const starting = role === "start" && context.start === void 0;
|
|
2176
|
+
const match = conversationMatch(input, role, this.locationIndex.locationOf(input.event));
|
|
2183
2177
|
const previous = context.matches.at(-1);
|
|
2184
2178
|
if (previous !== void 0 && previous.event.seq >= input.event.seq) throw new Error(`conversation Context ${key} received non-appended Match ${input.event.seq}`);
|
|
2185
|
-
if (
|
|
2179
|
+
if (starting && context.matches.length > 0) throw new Error(`conversation Context ${key} received an update before its start Match`);
|
|
2186
2180
|
context.matches.push(match);
|
|
2187
|
-
if (match.role === "start") {
|
|
2181
|
+
if (starting && match.role === "start") {
|
|
2188
2182
|
context.startSeq = input.event.seq;
|
|
2189
2183
|
context.start = match;
|
|
2190
2184
|
this.indexStartedContext(context);
|
|
@@ -2192,7 +2186,7 @@ window.__ModuleLoader__.load({
|
|
|
2192
2186
|
const owners = this.contextsBySeq.get(input.event.seq) ?? /* @__PURE__ */ new Set();
|
|
2193
2187
|
owners.add(context);
|
|
2194
2188
|
this.contextsBySeq.set(input.event.seq, owners);
|
|
2195
|
-
if (
|
|
2189
|
+
if (starting) this.replayContext(context);
|
|
2196
2190
|
else if (context.state !== void 0) {
|
|
2197
2191
|
const typed = contextSnapshot(context);
|
|
2198
2192
|
context.state = requireState(definition, "update", definition.update(typed, match));
|
|
@@ -2203,49 +2197,57 @@ window.__ModuleLoader__.load({
|
|
|
2203
2197
|
return definition.publication?.(match) ?? "immediate";
|
|
2204
2198
|
}
|
|
2205
2199
|
applyPendingMatches(pending, affected) {
|
|
2206
|
-
const startsByKind = /* @__PURE__ */ new Map();
|
|
2207
2200
|
for (const [key, entries] of pending) {
|
|
2208
2201
|
const first = entries[0];
|
|
2209
2202
|
if (first === void 0) continue;
|
|
2210
2203
|
let context = this.contexts.get(key);
|
|
2211
2204
|
context ??= this.createContext(first.definition, first.id, key);
|
|
2212
|
-
let discoveredStart;
|
|
2213
2205
|
const additions = entries.map((entry) => {
|
|
2214
2206
|
if (entry.definition !== context.definition || entry.id !== context.id) throw new Error(`conversation Context ${key} received inconsistent Definition identity`);
|
|
2215
|
-
if (entry.match.role === "start") {
|
|
2216
|
-
if (discoveredStart !== void 0 || context.start !== void 0) throw new Error(`conversation Context ${key} received more than one start Match`);
|
|
2217
|
-
discoveredStart = entry.match;
|
|
2218
|
-
}
|
|
2219
2207
|
const owners = this.contextsBySeq.get(entry.match.event.seq) ?? /* @__PURE__ */ new Set();
|
|
2220
2208
|
owners.add(context);
|
|
2221
2209
|
this.contextsBySeq.set(entry.match.event.seq, owners);
|
|
2222
2210
|
return entry.match;
|
|
2223
2211
|
}).sort((left, right) => left.event.seq - right.event.seq);
|
|
2224
2212
|
context.matches = mergeMatches(context.key, additions, context.matches);
|
|
2225
|
-
if (discoveredStart !== void 0) {
|
|
2226
|
-
context.start = discoveredStart;
|
|
2227
|
-
context.startSeq = discoveredStart.event.seq;
|
|
2228
|
-
const starts = startsByKind.get(context.kind) ?? [];
|
|
2229
|
-
starts.push(context);
|
|
2230
|
-
startsByKind.set(context.kind, starts);
|
|
2231
|
-
}
|
|
2232
|
-
if (context.start !== void 0 && context.matches[0] !== context.start) throw new Error(`conversation Context ${context.key} received an update before its start Match`);
|
|
2233
2213
|
affected.add(context);
|
|
2234
2214
|
this.markDirty(context);
|
|
2235
2215
|
}
|
|
2236
|
-
for (const [kind, contexts] of startsByKind) this.indexStartedContexts(kind, contexts);
|
|
2237
2216
|
}
|
|
2238
2217
|
replayContexts(contexts) {
|
|
2218
|
+
this.refreshStarts(contexts);
|
|
2239
2219
|
const ordered = [...contexts].sort((left, right) => (left.startSeq ?? Number.POSITIVE_INFINITY) - (right.startSeq ?? Number.POSITIVE_INFINITY));
|
|
2240
2220
|
for (const context of ordered) {
|
|
2241
2221
|
if (context.start === void 0) {
|
|
2242
2222
|
context.state = void 0;
|
|
2223
|
+
this.replaceDependencies(context, /* @__PURE__ */ new Map());
|
|
2224
|
+
context.revision++;
|
|
2225
|
+
this.revised.add(context);
|
|
2243
2226
|
this.markDirty(context);
|
|
2244
2227
|
continue;
|
|
2245
2228
|
}
|
|
2246
2229
|
this.replayContext(context);
|
|
2247
2230
|
}
|
|
2248
2231
|
}
|
|
2232
|
+
refreshStarts(contexts) {
|
|
2233
|
+
const changed = /* @__PURE__ */ new Set();
|
|
2234
|
+
const startsByKind = /* @__PURE__ */ new Map();
|
|
2235
|
+
for (const context of contexts) {
|
|
2236
|
+
const start = context.matches.find((match) => match.role === "start");
|
|
2237
|
+
if (start === context.start) continue;
|
|
2238
|
+
context.start = start;
|
|
2239
|
+
context.startSeq = start?.event.seq;
|
|
2240
|
+
changed.add(context);
|
|
2241
|
+
const starts = startsByKind.get(context.kind) ?? [];
|
|
2242
|
+
if (start !== void 0) starts.push(context);
|
|
2243
|
+
startsByKind.set(context.kind, starts);
|
|
2244
|
+
}
|
|
2245
|
+
for (const [kind, starts] of startsByKind) {
|
|
2246
|
+
const existing = this.contextsByKind.get(kind) ?? [];
|
|
2247
|
+
this.contextsByKind.set(kind, existing.filter((context) => !changed.has(context)));
|
|
2248
|
+
this.indexStartedContexts(kind, starts);
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2249
2251
|
replayContext(context) {
|
|
2250
2252
|
const start = context.start;
|
|
2251
2253
|
if (start === void 0) {
|
|
@@ -2260,7 +2262,7 @@ window.__ModuleLoader__.load({
|
|
|
2260
2262
|
this.replaceDependencies(context, dependencies);
|
|
2261
2263
|
for (let index = 1; index < context.matches.length; index++) {
|
|
2262
2264
|
const match = context.matches[index];
|
|
2263
|
-
if (match === void 0
|
|
2265
|
+
if (match === void 0) continue;
|
|
2264
2266
|
const typed = contextSnapshot(context);
|
|
2265
2267
|
context.state = requireState(context.definition, "update", context.definition.update(typed, match));
|
|
2266
2268
|
}
|
|
@@ -14455,6 +14457,7 @@ window.__ModuleLoader__.load({
|
|
|
14455
14457
|
"tool.title.createGoal": "创建目标",
|
|
14456
14458
|
"tool.title.getGoal": "查看目标",
|
|
14457
14459
|
"tool.title.updateGoal": "更新目标",
|
|
14460
|
+
"tool.preparing.content": "正在准备内容 {kilobytes}KB",
|
|
14458
14461
|
"tool.title.createSchedule": "创建定时任务",
|
|
14459
14462
|
"tool.title.listSchedules": "查看定时任务",
|
|
14460
14463
|
"tool.title.deleteSchedule": "删除定时任务",
|
|
@@ -14500,14 +14503,14 @@ window.__ModuleLoader__.load({
|
|
|
14500
14503
|
"tool.title.queryRuntime": "查询运行时",
|
|
14501
14504
|
"tool.title.inspectPlugins": "检查动态插件",
|
|
14502
14505
|
"tool.title.workflow": "运行工作流",
|
|
14503
|
-
"tool.title.ralph": "
|
|
14506
|
+
"tool.title.ralph": "运行循环工作流",
|
|
14504
14507
|
"tool.title.readEvent": "读取事件",
|
|
14505
14508
|
"tool.title.searchEvents": "搜索事件",
|
|
14506
14509
|
"tool.title.traceEvent": "追踪事件",
|
|
14507
14510
|
"tool.title.searchSessions": "搜索会话",
|
|
14508
14511
|
"tool.title.traceSession": "追踪会话",
|
|
14509
14512
|
"tool.title.listModels": "查看可用模型",
|
|
14510
|
-
"tool.title.subagent": "
|
|
14513
|
+
"tool.title.subagent": "创建代理",
|
|
14511
14514
|
"tool.title.listAgents": "查看代理",
|
|
14512
14515
|
"tool.title.sendMessage": "发送消息",
|
|
14513
14516
|
"tool.title.interruptAgent": "中断代理",
|
|
@@ -14529,7 +14532,7 @@ window.__ModuleLoader__.load({
|
|
|
14529
14532
|
"tool.title.getTeamTask": "读取团队任务",
|
|
14530
14533
|
"tool.title.updateTeamTask": "更新团队任务",
|
|
14531
14534
|
"tool.title.listTeamTasks": "查看团队任务",
|
|
14532
|
-
"tool.title.waitAgent": "
|
|
14535
|
+
"tool.title.waitAgent": "等待子智能体",
|
|
14533
14536
|
"detail.recordedResult": "调用结果",
|
|
14534
14537
|
"detail.empty": "暂无结果",
|
|
14535
14538
|
"detail.none": "无",
|
|
@@ -14613,8 +14616,8 @@ window.__ModuleLoader__.load({
|
|
|
14613
14616
|
"detail.receipt.signal": "信号已发送",
|
|
14614
14617
|
"detail.receipt.closed": "已关闭",
|
|
14615
14618
|
"detail.receipt.closing": "关闭中",
|
|
14616
|
-
"detail.wait.noProgress": "
|
|
14617
|
-
"detail.wait.title": "
|
|
14619
|
+
"detail.wait.noProgress": "没有正在运行的子智能体",
|
|
14620
|
+
"detail.wait.title": "子智能体状态",
|
|
14618
14621
|
"detail.wait.timeout": "等待超时",
|
|
14619
14622
|
"detail.wait.changed": "检测到变化",
|
|
14620
14623
|
"detail.agent.reply": "代理回复",
|
|
@@ -14652,6 +14655,7 @@ window.__ModuleLoader__.load({
|
|
|
14652
14655
|
"bash.failed": "失败",
|
|
14653
14656
|
"bash.stopped": "已停止",
|
|
14654
14657
|
"row.running": "运行中",
|
|
14658
|
+
"row.preparing": "正在准备调用",
|
|
14655
14659
|
"row.failed": "失败",
|
|
14656
14660
|
"row.stopped": "已停止",
|
|
14657
14661
|
"row.input": "输入",
|
|
@@ -14664,7 +14668,7 @@ window.__ModuleLoader__.load({
|
|
|
14664
14668
|
"tool.title.edit": "编辑",
|
|
14665
14669
|
"tool.title.code": "代码",
|
|
14666
14670
|
"tool.title.generic": "工具调用",
|
|
14667
|
-
"tool.title.inspect": "
|
|
14671
|
+
"tool.title.inspect": "查询 Cordis 环境",
|
|
14668
14672
|
"tool.title.runCordis": "运行 Cordis 插件",
|
|
14669
14673
|
"tool.title.stopCordis": "停止 Cordis 插件",
|
|
14670
14674
|
"tool.title.removeCordis": "移除 Cordis 插件",
|
|
@@ -14677,8 +14681,6 @@ window.__ModuleLoader__.load({
|
|
|
14677
14681
|
"tool.autoReviewRejected": "Auto review 已拒绝",
|
|
14678
14682
|
"tool.autoReviewNotExecuted": "工具未执行。原因:{reason}",
|
|
14679
14683
|
"tool.autoReviewReasonFallback": "Auto review 未授权此次操作",
|
|
14680
|
-
"diff.files.one": "{count} 个文件",
|
|
14681
|
-
"diff.files.other": "{count} 个文件",
|
|
14682
14684
|
"diff.collapseAria": "收起差异",
|
|
14683
14685
|
"diff.expandAria": "展开其余 {count} 行差异",
|
|
14684
14686
|
"diff.expandRest": "… 其余 {count} 行",
|
|
@@ -14805,6 +14807,7 @@ window.__ModuleLoader__.load({
|
|
|
14805
14807
|
"tool.title.createGoal": "Create goal",
|
|
14806
14808
|
"tool.title.getGoal": "View goal",
|
|
14807
14809
|
"tool.title.updateGoal": "Update goal",
|
|
14810
|
+
"tool.preparing.content": "Preparing content {kilobytes}KB",
|
|
14808
14811
|
"tool.title.createSchedule": "Create reminder",
|
|
14809
14812
|
"tool.title.listSchedules": "List reminders",
|
|
14810
14813
|
"tool.title.deleteSchedule": "Delete reminder",
|
|
@@ -14850,15 +14853,15 @@ window.__ModuleLoader__.load({
|
|
|
14850
14853
|
"tool.title.queryRuntime": "Query runtime",
|
|
14851
14854
|
"tool.title.inspectPlugins": "Inspect plugins",
|
|
14852
14855
|
"tool.title.workflow": "Run workflow",
|
|
14853
|
-
"tool.title.ralph": "Run
|
|
14856
|
+
"tool.title.ralph": "Run ralph loop",
|
|
14854
14857
|
"tool.title.readEvent": "Read event",
|
|
14855
14858
|
"tool.title.searchEvents": "Search events",
|
|
14856
14859
|
"tool.title.traceEvent": "Trace event",
|
|
14857
14860
|
"tool.title.searchSessions": "Search sessions",
|
|
14858
14861
|
"tool.title.traceSession": "Trace session",
|
|
14859
14862
|
"tool.title.listModels": "List models",
|
|
14860
|
-
"tool.title.subagent": "
|
|
14861
|
-
"tool.title.listAgents": "List
|
|
14863
|
+
"tool.title.subagent": "Create subagent",
|
|
14864
|
+
"tool.title.listAgents": "List subagents",
|
|
14862
14865
|
"tool.title.sendMessage": "Send message",
|
|
14863
14866
|
"tool.title.interruptAgent": "Interrupt agent",
|
|
14864
14867
|
"tool.title.listJobs": "List background jobs",
|
|
@@ -14879,7 +14882,7 @@ window.__ModuleLoader__.load({
|
|
|
14879
14882
|
"tool.title.getTeamTask": "Read team task",
|
|
14880
14883
|
"tool.title.updateTeamTask": "Update team task",
|
|
14881
14884
|
"tool.title.listTeamTasks": "List team tasks",
|
|
14882
|
-
"tool.title.waitAgent": "Wait for
|
|
14885
|
+
"tool.title.waitAgent": "Wait for subagent",
|
|
14883
14886
|
"detail.recordedResult": "Recorded result",
|
|
14884
14887
|
"detail.empty": "No results",
|
|
14885
14888
|
"detail.none": "None",
|
|
@@ -14963,8 +14966,8 @@ window.__ModuleLoader__.load({
|
|
|
14963
14966
|
"detail.receipt.signal": "Signal delivered",
|
|
14964
14967
|
"detail.receipt.closed": "Closed",
|
|
14965
14968
|
"detail.receipt.closing": "Closing",
|
|
14966
|
-
"detail.wait.noProgress": "No active
|
|
14967
|
-
"detail.wait.title": "
|
|
14969
|
+
"detail.wait.noProgress": "No active subagents",
|
|
14970
|
+
"detail.wait.title": "Subagent activity",
|
|
14968
14971
|
"detail.wait.timeout": "Wait timed out",
|
|
14969
14972
|
"detail.wait.changed": "Change detected",
|
|
14970
14973
|
"detail.agent.reply": "Agent response",
|
|
@@ -15002,6 +15005,7 @@ window.__ModuleLoader__.load({
|
|
|
15002
15005
|
"bash.failed": "Failed",
|
|
15003
15006
|
"bash.stopped": "Stopped",
|
|
15004
15007
|
"row.running": "Running",
|
|
15008
|
+
"row.preparing": "Preparing tool call",
|
|
15005
15009
|
"row.failed": "Failed",
|
|
15006
15010
|
"row.stopped": "Stopped",
|
|
15007
15011
|
"row.input": "IN",
|
|
@@ -15014,7 +15018,7 @@ window.__ModuleLoader__.load({
|
|
|
15014
15018
|
"tool.title.edit": "Edit",
|
|
15015
15019
|
"tool.title.code": "Code",
|
|
15016
15020
|
"tool.title.generic": "Tool call",
|
|
15017
|
-
"tool.title.inspect": "
|
|
15021
|
+
"tool.title.inspect": "Query Cordis environment",
|
|
15018
15022
|
"tool.title.runCordis": "Run Cordis Plugin",
|
|
15019
15023
|
"tool.title.stopCordis": "Stop Cordis Plugin",
|
|
15020
15024
|
"tool.title.removeCordis": "Remove Cordis Plugin",
|
|
@@ -15027,8 +15031,6 @@ window.__ModuleLoader__.load({
|
|
|
15027
15031
|
"tool.autoReviewRejected": "Rejected by Auto review",
|
|
15028
15032
|
"tool.autoReviewNotExecuted": "Tool was not executed. Reason: {reason}",
|
|
15029
15033
|
"tool.autoReviewReasonFallback": "Auto review did not authorize this action",
|
|
15030
|
-
"diff.files.one": "{count} file",
|
|
15031
|
-
"diff.files.other": "{count} files",
|
|
15032
15034
|
"diff.collapseAria": "Collapse diff",
|
|
15033
15035
|
"diff.expandAria": "Expand {count} more diff lines",
|
|
15034
15036
|
"diff.expandRest": "… {count} more lines",
|
|
@@ -15079,7 +15081,7 @@ window.__ModuleLoader__.load({
|
|
|
15079
15081
|
};
|
|
15080
15082
|
//#endregion
|
|
15081
15083
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-conversation/src/client/queue/QueueDock.module.css.mjs
|
|
15082
|
-
const css$6 = "._7yHdaG_dock{box-sizing:border-box;width:calc(100% - var(--dsh-composer-side-clearance) - var(--dsh-composer-side-clearance) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));max-width:calc(var(--dsh-composer-card-max-width) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));margin:0 auto calc(0px - var(--dsh-composer-stack-gap) - 3px);padding:0 var(--dsh-composer-dock-inset);flex:none}._7yHdaG_panel{isolation:isolate;--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px 12px 0 0;width:100%;padding:2px 0;position:relative;overflow:hidden}._7yHdaG_panel:before{z-index:-1;border-radius:inherit;background:var(--dsw-specific-menu);backdrop-filter:var(--dsw-menu-backdrop-filter);content:\"\";pointer-events:none;position:absolute;inset:0}._7yHdaG_panel:after{border:.5px solid var(--dsw-alias-border-l1);border-radius:inherit;content:\"\";pointer-events:none;border-bottom:none;position:absolute;inset:0}._7yHdaG_header{box-sizing:border-box;width:100%;height:36px;color:var(--dsw-alias-label-primary);text-align:left;cursor:pointer;background:0 0;border:none;border-radius:8px;align-items:center;gap:10px;padding:4px 12px;display:flex}._7yHdaG_header:focus-visible{outline:2px solid var(--dsw-alias-label-tertiary);outline-offset:-2px}._7yHdaG_header:disabled{cursor:default}._7yHdaG_lead{color:var(--dsw-alias-label-tertiary);flex:none;place-items:center;display:grid}._7yHdaG_count{min-width:0;font-family:Inter, var(--dsw-font-family);flex:auto;font-size:13px;font-weight:500;line-height:24px}._7yHdaG_chevron{width:14px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none;place-items:center;display:grid}._7yHdaG_list{max-height:180px;margin:0;padding:0;list-style:none;overflow-y:auto}._7yHdaG_row{box-sizing:border-box;border-radius:8px;align-items:center;gap:10px;width:100%;height:36px;padding:4px 5px 4px 12px;display:flex}._7yHdaG_row+._7yHdaG_row{box-shadow:inset 0 1px 0 var(--dsw-alias-border-l1)}._7yHdaG_attachments{flex:none;gap:4px;min-width:0;max-width:55%;display:flex;overflow:hidden}._7yHdaG_pendingRow ._7yHdaG_attachments{flex-shrink:1}._7yHdaG_file{border:.5px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);box-sizing:border-box;border-radius:6px;flex:0 180px;align-items:center;gap:4px;min-width:74px;height:24px;padding:0 6px;display:inline-flex;overflow:hidden}._7yHdaG_fileIcon{flex:none;width:16px;height:16px;display:inline-flex}._7yHdaG_fileName{min-width:0;color:var(--dsw-alias-label-primary-dimmed);font:var(--dsw-font-xs-13);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}._7yHdaG_fileSize{color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none;font-size:10px}._7yHdaG_thumb{border:.5px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);object-fit:cover;border-radius:4px;width:24px;height:24px}._7yHdaG_preview,._7yHdaG_editor{min-width:0;font:var(--dsw-font-xs-13);font-family:Inter, var(--dsw-font-family);flex:auto}._7yHdaG_preview{color:var(--dsw-alias-label-primary-dimmed);text-overflow:ellipsis;white-space:nowrap;word-break:break-word;overflow:hidden}._7yHdaG_editor{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-bg-base);height:28px;color:var(--dsw-alias-label-primary);border-radius:6px;outline:none;padding:
|
|
15084
|
+
const css$6 = "._7yHdaG_dock{box-sizing:border-box;width:calc(100% - var(--dsh-composer-side-clearance) - var(--dsh-composer-side-clearance) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));max-width:calc(var(--dsh-composer-card-max-width) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));margin:0 auto calc(0px - var(--dsh-composer-stack-gap) - 3px);padding:0 var(--dsh-composer-dock-inset);flex:none}._7yHdaG_panel{isolation:isolate;--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px 12px 0 0;width:100%;padding:2px 0;position:relative;overflow:hidden}._7yHdaG_panel:before{z-index:-1;border-radius:inherit;background:var(--dsw-specific-menu);backdrop-filter:var(--dsw-menu-backdrop-filter);content:\"\";pointer-events:none;position:absolute;inset:0}._7yHdaG_panel:after{border:.5px solid var(--dsw-alias-border-l1);border-radius:inherit;content:\"\";pointer-events:none;border-bottom:none;position:absolute;inset:0}._7yHdaG_header{box-sizing:border-box;width:100%;height:36px;color:var(--dsw-alias-label-primary);text-align:left;cursor:pointer;background:0 0;border:none;border-radius:8px;align-items:center;gap:10px;padding:4px 12px;display:flex}._7yHdaG_header:focus-visible{outline:2px solid var(--dsw-alias-label-tertiary);outline-offset:-2px}._7yHdaG_header:disabled{cursor:default}._7yHdaG_lead{color:var(--dsw-alias-label-tertiary);flex:none;place-items:center;display:grid}._7yHdaG_count{min-width:0;font-family:Inter, var(--dsw-font-family);flex:auto;font-size:13px;font-weight:500;line-height:24px}._7yHdaG_chevron{width:14px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none;place-items:center;display:grid}._7yHdaG_list{max-height:180px;margin:0;padding:0;list-style:none;overflow-y:auto}._7yHdaG_row{box-sizing:border-box;border-radius:8px;align-items:center;gap:10px;width:100%;min-height:36px;padding:4px 5px 4px 12px;display:flex}._7yHdaG_row+._7yHdaG_row{box-shadow:inset 0 1px 0 var(--dsw-alias-border-l1)}._7yHdaG_attachments{flex:none;gap:4px;min-width:0;max-width:55%;display:flex;overflow:hidden}._7yHdaG_pendingRow ._7yHdaG_attachments{flex-shrink:1}._7yHdaG_file{border:.5px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);box-sizing:border-box;border-radius:6px;flex:0 180px;align-items:center;gap:4px;min-width:74px;height:24px;padding:0 6px;display:inline-flex;overflow:hidden}._7yHdaG_fileIcon{flex:none;width:16px;height:16px;display:inline-flex}._7yHdaG_fileName{min-width:0;color:var(--dsw-alias-label-primary-dimmed);font:var(--dsw-font-xs-13);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}._7yHdaG_fileSize{color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none;font-size:10px}._7yHdaG_thumb{border:.5px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);object-fit:cover;border-radius:4px;width:24px;height:24px}._7yHdaG_preview,._7yHdaG_editor{min-width:0;font:var(--dsw-font-xs-13);font-family:Inter, var(--dsw-font-family);flex:auto}._7yHdaG_preview{color:var(--dsw-alias-label-primary-dimmed);text-overflow:ellipsis;white-space:nowrap;word-break:break-word;overflow:hidden}._7yHdaG_editor{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-bg-base);min-height:28px;max-height:127px;color:var(--dsw-alias-label-primary);resize:none;border-radius:6px;outline:none;padding:3px 8px;overflow-y:auto}._7yHdaG_editor:focus{border-color:var(--dsw-alias-state-business-primary)}._7yHdaG_actions{flex:none;align-items:center;gap:10px;display:flex}._7yHdaG_status{color:var(--dsw-alias-label-tertiary);font:var(--dsw-font-xs-13);white-space:nowrap;flex:none}._7yHdaG_action{corner-shape:round;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:999px;flex:none;place-items:center;padding:0;display:grid}._7yHdaG_action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}._7yHdaG_action:focus-visible{outline:2px solid var(--dsw-alias-label-tertiary);outline-offset:-2px}._7yHdaG_action:disabled{cursor:default;opacity:.45}";
|
|
15083
15085
|
const tagId$6 = "@deepseek-ai/dsh-client-ui-conversation/QueueDock.module.css";
|
|
15084
15086
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$6) + "]") === null) {
|
|
15085
15087
|
const tag = document.createElement("style");
|
|
@@ -15198,13 +15200,55 @@ window.__ModuleLoader__.load({
|
|
|
15198
15200
|
});
|
|
15199
15201
|
}
|
|
15200
15202
|
/**
|
|
15203
|
+
* Inline editor for one queued row. A textarea rather than an input: HTML
|
|
15204
|
+
* strips newlines from single-line input values, so editing a multi-line
|
|
15205
|
+
* queued message through one rewrites it as a single line. It grows with its
|
|
15206
|
+
* content up to the CSS cap, then scrolls. Enter saves, Shift+Enter breaks the
|
|
15207
|
+
* line, Escape cancels.
|
|
15208
|
+
*/
|
|
15209
|
+
function QueueEditor({ text, label, onChange, onSave, onCancel }) {
|
|
15210
|
+
const ref = (0, react.useRef)(null);
|
|
15211
|
+
(0, react.useLayoutEffect)(() => {
|
|
15212
|
+
const node = ref.current;
|
|
15213
|
+
/* v8 ignore next -- the ref is attached before layout effects run. */
|
|
15214
|
+
if (node === null) return;
|
|
15215
|
+
node.style.height = "auto";
|
|
15216
|
+
node.style.height = `${node.scrollHeight + node.offsetHeight - node.clientHeight}px`;
|
|
15217
|
+
}, [text]);
|
|
15218
|
+
return (0, react_jsx_runtime.jsx)("textarea", {
|
|
15219
|
+
ref,
|
|
15220
|
+
autoFocus: true,
|
|
15221
|
+
rows: 1,
|
|
15222
|
+
className: QueueDock_module_css_default.editor,
|
|
15223
|
+
"aria-label": label,
|
|
15224
|
+
value: text,
|
|
15225
|
+
onChange: (event) => {
|
|
15226
|
+
onChange(event.currentTarget.value);
|
|
15227
|
+
},
|
|
15228
|
+
onKeyDown: (event) => {
|
|
15229
|
+
if (event.key === "Escape") {
|
|
15230
|
+
onCancel();
|
|
15231
|
+
return;
|
|
15232
|
+
}
|
|
15233
|
+
if (event.key !== "Enter" || event.shiftKey || event.nativeEvent.isComposing) return;
|
|
15234
|
+
event.preventDefault();
|
|
15235
|
+
onSave();
|
|
15236
|
+
}
|
|
15237
|
+
});
|
|
15238
|
+
}
|
|
15239
|
+
/**
|
|
15201
15240
|
* Queue strip: one item renders directly; multiple items default to a
|
|
15202
|
-
* collapsible count header; an empty queue renders nothing. Local submissions
|
|
15241
|
+
* collapsible count header; an empty queue renders nothing. Local queued submissions
|
|
15203
15242
|
* show sending status and disabled actions until their Host queue rows arrive.
|
|
15204
15243
|
*/
|
|
15205
15244
|
function QueueDock({ useSession, useProjection, updateQueue, notify, loadImage, t }) {
|
|
15206
|
-
const
|
|
15245
|
+
const inbox = useProjection("inbox");
|
|
15207
15246
|
const pendingSubmissions = useSession((s) => s.pendingSubmissions);
|
|
15247
|
+
const queue = (0, react.useMemo)(() => {
|
|
15248
|
+
const rows = inbox?.["next-turn"] ?? EMPTY_QUEUE;
|
|
15249
|
+
const inChat = new Set(pendingSubmissions.filter((item) => item.placement === "transcript").map((item) => item.requestId));
|
|
15250
|
+
return inChat.size === 0 ? rows : rows.filter(({ source }) => source.kind !== "user" || !("rpcId" in source) || !inChat.has(source.rpcId));
|
|
15251
|
+
}, [inbox, pendingSubmissions]);
|
|
15208
15252
|
const pendingQueue = (0, react.useMemo)(() => {
|
|
15209
15253
|
const admitted = new Set(queue.flatMap(({ source }) => source.kind === "user" && "rpcId" in source ? [source.rpcId] : []));
|
|
15210
15254
|
return pendingSubmissions.filter((submission) => submission.placement === "queued" && !admitted.has(submission.requestId));
|
|
@@ -15302,26 +15346,20 @@ window.__ModuleLoader__.load({
|
|
|
15302
15346
|
"aria-hidden": true,
|
|
15303
15347
|
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconQueueOutlineRegular, {})
|
|
15304
15348
|
}),
|
|
15305
|
-
editing?.id === row.id ? (0, react_jsx_runtime.jsx)(
|
|
15306
|
-
|
|
15307
|
-
|
|
15308
|
-
|
|
15309
|
-
value: editing.text,
|
|
15310
|
-
onChange: (event) => {
|
|
15349
|
+
editing?.id === row.id ? (0, react_jsx_runtime.jsx)(QueueEditor, {
|
|
15350
|
+
text: editing.text,
|
|
15351
|
+
label: t("queue.edit"),
|
|
15352
|
+
onChange: (text) => {
|
|
15311
15353
|
setEditing({
|
|
15312
15354
|
id: row.id,
|
|
15313
|
-
text
|
|
15355
|
+
text
|
|
15314
15356
|
});
|
|
15315
15357
|
},
|
|
15316
|
-
|
|
15317
|
-
|
|
15318
|
-
|
|
15319
|
-
|
|
15320
|
-
|
|
15321
|
-
if (event.key === "Enter" && !event.nativeEvent.isComposing) {
|
|
15322
|
-
event.preventDefault();
|
|
15323
|
-
saveEdit();
|
|
15324
|
-
}
|
|
15358
|
+
onSave: () => {
|
|
15359
|
+
saveEdit();
|
|
15360
|
+
},
|
|
15361
|
+
onCancel: () => {
|
|
15362
|
+
setEditing(null);
|
|
15325
15363
|
}
|
|
15326
15364
|
}) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [attachments.length > 0 && (0, react_jsx_runtime.jsx)("span", {
|
|
15327
15365
|
className: QueueDock_module_css_default.attachments,
|
|
@@ -15340,6 +15378,7 @@ window.__ModuleLoader__.load({
|
|
|
15340
15378
|
queueMutable && (0, react_jsx_runtime.jsx)("div", {
|
|
15341
15379
|
className: QueueDock_module_css_default.actions,
|
|
15342
15380
|
children: editing?.id === row.id ? (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
15381
|
+
portal: true,
|
|
15343
15382
|
label: t("queue.save"),
|
|
15344
15383
|
side: "bottom",
|
|
15345
15384
|
delayMs: 500,
|
|
@@ -15354,6 +15393,7 @@ window.__ModuleLoader__.load({
|
|
|
15354
15393
|
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutlineRegular, { size: 14 })
|
|
15355
15394
|
})
|
|
15356
15395
|
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
15396
|
+
portal: true,
|
|
15357
15397
|
label: t("queue.cancelEdit"),
|
|
15358
15398
|
side: "bottom",
|
|
15359
15399
|
delayMs: 500,
|
|
@@ -15369,6 +15409,7 @@ window.__ModuleLoader__.load({
|
|
|
15369
15409
|
})
|
|
15370
15410
|
})] }) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
15371
15411
|
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
15412
|
+
portal: true,
|
|
15372
15413
|
label: t("queue.edit"),
|
|
15373
15414
|
side: "bottom",
|
|
15374
15415
|
delayMs: 500,
|
|
@@ -15389,6 +15430,7 @@ window.__ModuleLoader__.load({
|
|
|
15389
15430
|
})
|
|
15390
15431
|
}),
|
|
15391
15432
|
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
15433
|
+
portal: true,
|
|
15392
15434
|
label: t("queue.remove"),
|
|
15393
15435
|
side: "bottom",
|
|
15394
15436
|
delayMs: 500,
|
|
@@ -15404,6 +15446,7 @@ window.__ModuleLoader__.load({
|
|
|
15404
15446
|
})
|
|
15405
15447
|
}),
|
|
15406
15448
|
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
15449
|
+
portal: true,
|
|
15407
15450
|
label: t("queue.steer"),
|
|
15408
15451
|
side: "bottom",
|
|
15409
15452
|
delayMs: 500,
|
|
@@ -15620,7 +15663,7 @@ window.__ModuleLoader__.load({
|
|
|
15620
15663
|
}
|
|
15621
15664
|
//#endregion
|
|
15622
15665
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-conversation/src/client/skeleton/ConversationRoot.module.css.mjs
|
|
15623
|
-
const css$4 = ".wSkVaW_root{background:var(--dsw-alias-bg-base);flex-direction:column;min-width:0;height:100%;display:flex;position:relative}.wSkVaW_header{box-sizing:border-box;border-bottom:.5px solid var(--dsw-alias-border-l3);flex:none;grid-template-columns:auto minmax(0,1fr);min-height:76px;padding:10px 28px 0 20px;display:grid}.wSkVaW_header:where(:not(:has(.wSkVaW_tabs))){min-height:0;padding-bottom:10px}.wSkVaW_headerBlank{border-bottom:none;min-height:0;padding-bottom:0}.wSkVaW_headerBlank .wSkVaW_headerCorner{margin-left:auto}html:not([data-platform=darwin]) .wSkVaW_headerSessionless{padding-top:0}html:not([data-platform=darwin]) .wSkVaW_headerSessionless .wSkVaW_titleRow{min-height:0}[data-platform=darwin] .wSkVaW_headerLeading,[data-platform=darwin] .wSkVaW_headerActions,[data-platform=darwin] .wSkVaW_headerUtilities,[data-platform=darwin] .wSkVaW_headerCorner{-webkit-app-region:no-drag}.wSkVaW_titleRow{min-height:30px;grid-column:2;align-items:center;gap:0;padding-inline-start:max(0px, calc(var(--dsh-frame-leading-clearance,0px) - 20px));display:flex}.wSkVaW_titleCluster{flex:1;align-items:center;gap:10px;min-width:0;display:flex}.wSkVaW_headerLeading{flex:none;grid-area:1/1;align-items:center;gap:8px;display:flex}.wSkVaW_crumbs{white-space:nowrap;align-items:center;gap:4px;min-width:0;display:flex;overflow:hidden}.wSkVaW_crumbSeg{align-items:center;gap:4px;min-width:0;display:inline-flex}.wSkVaW_crumbSep{color:var(--dsw-alias-label-caption);font-size:14px;line-height:20px}.wSkVaW_crumb{max-width:220px;color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;cursor:pointer;background:0 0;border:none;border-radius:12px;padding:4px 8px;font-size:14px;line-height:20px;display:inline-block;overflow:hidden}.wSkVaW_crumbSubagent{font-size:12px;line-height:18px}button.wSkVaW_crumb:hover{background:var(--dsw-alias-interactive-bg-hover)}.wSkVaW_crumbCurrent{color:var(--dsw-alias-label-primary);cursor:default;font-weight:500}.wSkVaW_headerActions{flex:none;align-items:center;gap:8px;display:flex}.wSkVaW_headerUtilities{flex:none;align-items:center;gap:8px;margin-left:20px;display:flex}.wSkVaW_headerUtilities:empty{display:none}.wSkVaW_headerCorner{flex:none;align-items:center;margin-left:8px;margin-right:-16px;display:flex}.wSkVaW_headerCorner:empty{display:none}.wSkVaW_tabs{z-index:1;grid-column:1/-1;gap:36px;margin-top:10px;padding-left:8px;display:flex;position:relative}.wSkVaW_tab{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;padding:0 0 9px;font-size:13px;font-weight:500;line-height:16px;position:relative}.wSkVaW_tab:after{content:\"\";background:0 0;border-radius:2px;height:2px;position:absolute;bottom:-1px;left:0;right:0}.wSkVaW_tabActive{color:var(--dsw-alias-state-business-primary)}.wSkVaW_tabActive:after{background:var(--dsw-alias-state-business-primary)}.wSkVaW_viewArea{flex-direction:column;flex:1;min-height:0;display:flex}.wSkVaW_widthHandle{z-index:0;width:min(10px, calc((100% - var(--dsh-chat-content-width)) / 2 - 24px - 24px));cursor:col-resize;position:absolute;top:0;bottom:0}.wSkVaW_widthHandle[data-side=left]{right:calc(50% + var(--dsh-chat-content-width) / 2 + 24px)}.wSkVaW_widthHandle[data-side=right]{left:calc(50% + var(--dsh-chat-content-width) / 2 + 24px)}.wSkVaW_widthHandle:after{content:\"\";background:linear-gradient(to bottom, transparent calc(var(--dsh-width-handle-pointer-y,50%) - 36px), var(--dsw-alias-scrollbar-bg-l1) calc(var(--dsh-width-handle-pointer-y,50%) - 8px), var(--dsw-alias-scrollbar-bg-l1) calc(var(--dsh-width-handle-pointer-y,50%) + 8px), transparent calc(var(--dsh-width-handle-pointer-y,50%) + 36px));opacity:0;pointer-events:none;border-radius:2px;width:2px;position:absolute;top:0;bottom:0}.wSkVaW_widthHandle[data-side=left]:after{right:4px}.wSkVaW_widthHandle[data-side=right]:after{left:4px}.wSkVaW_widthHandle:hover:after,.wSkVaW_widthHandle[data-dragging]:after{opacity:1}.wSkVaW_widthHandle[data-dragging]{z-index:8}.wSkVaW_root:has([data-conversation-composer-overlay]) .wSkVaW_widthHandle{display:none}.wSkVaW_composerStack{--dsh-composer-stack-gap:6px;gap:var(--dsh-composer-stack-gap);flex-direction:column;display:flex}.wSkVaW_composerSeat{--dsh-composer-text-max-height:336px;flex-direction:column;flex:none;display:flex}.wSkVaW_root[data-phase=active]{overflow:hidden}.wSkVaW_root[data-phase=active] .wSkVaW_header{flex:none}.wSkVaW_body{--dsh-chat-content-width:var(--dsh-chat-user-width,clamp(680px, calc(var(--dsh-conversation-column-width,0px) * .64), 920px));--dsh-composer-card-max-width:calc(var(--dsh-chat-content-width) + 32px);--dsh-composer-side-clearance:16px;--dsh-composer-dock-inset:8px;flex-direction:column;flex:1;min-height:0;display:flex;position:relative}.wSkVaW_embeddedBody{--dsh-chat-content-width:min(calc(100% - 32px), 920px);--dsh-composer-card-max-width:min(calc(100% - 16px), 952px);--dsh-composer-side-clearance:8px;--dsh-composer-dock-inset:8px;overflow:hidden}.wSkVaW_scrollBody{scrollbar-gutter:stable;flex-direction:column;flex:1;min-height:0;margin-right:2px;display:flex;overflow-y:auto}.wSkVaW_scrollBody::-webkit-scrollbar-track{margin:2px}.wSkVaW_root[data-phase=active] .wSkVaW_viewArea,.wSkVaW_embeddedBody[data-content-phase=active] .wSkVaW_viewArea{flex:1 0 auto;min-height:auto}.wSkVaW_root[data-phase=active] .wSkVaW_composerSeat,.wSkVaW_embeddedBody[data-content-phase=active] .wSkVaW_composerSeat{z-index:7;background:linear-gradient(180deg, color-mix(in srgb, var(--dsw-alias-bg-base) 0%, transparent) 0px, var(--dsw-alias-bg-base) 36px);position:sticky;bottom:0}.wSkVaW_root[data-phase=active] .wSkVaW_composerSeat:has([data-trigger-menu]){z-index:9}.wSkVaW_scrollBody:has([data-conversation-composer-overlay]){scrollbar-gutter:auto;position:relative;overflow:hidden auto}.wSkVaW_scrollBody:has([data-conversation-composer-overlay])>[data-slot=conversation\\.session]>.wSkVaW_viewArea{flex:1 1 0;min-height:0;overflow:hidden}.wSkVaW_scrollBody:has([data-conversation-composer-overlay])>.wSkVaW_composerSeat{right:var(--dsh-scrollbar-width);position:absolute;bottom:0;left:0}.wSkVaW_composerHero{width:min(calc(var(--dsh-composer-card-max-width) + 2 * var(--dsh-composer-side-clearance)), 100%);z-index:1;align-self:center;gap:8px;padding-bottom:32px}.wSkVaW_heroWorkspaceRow{align-items:center;gap:2px;min-width:0;margin-top:4px;padding:0 16px 0 20px;display:flex}.wSkVaW_root[data-phase=hero] .wSkVaW_scrollBody,.wSkVaW_embeddedBody[data-content-phase=hero] .wSkVaW_scrollBody{justify-content:center;overflow-y:auto}.wSkVaW_root[data-phase=settling] .wSkVaW_composerSeat,.wSkVaW_embeddedBody[data-content-phase=settling] .wSkVaW_composerSeat{visibility:hidden}";
|
|
15666
|
+
const css$4 = ".wSkVaW_root{background:var(--dsw-alias-bg-base);flex-direction:column;min-width:0;height:100%;display:flex;position:relative}.wSkVaW_header{box-sizing:border-box;border-bottom:.5px solid var(--dsw-alias-border-l3);flex:none;grid-template-columns:auto minmax(0,1fr);min-height:76px;padding:10px 28px 0 20px;display:grid}.wSkVaW_header:where(:not(:has(.wSkVaW_tabs))){min-height:0;padding-bottom:10px}.wSkVaW_headerBlank{border-bottom:none;min-height:0;padding-bottom:0}.wSkVaW_headerBlank .wSkVaW_headerCorner{margin-left:auto}html:not([data-platform=darwin]) .wSkVaW_headerSessionless{padding-top:0}html:not([data-platform=darwin]) .wSkVaW_headerSessionless .wSkVaW_titleRow{min-height:0}[data-platform=darwin] .wSkVaW_headerLeading,[data-platform=darwin] .wSkVaW_headerActions,[data-platform=darwin] .wSkVaW_headerUtilities,[data-platform=darwin] .wSkVaW_headerCorner{-webkit-app-region:no-drag}.wSkVaW_titleRow{min-height:30px;grid-column:2;align-items:center;gap:0;padding-inline-start:max(0px, calc(var(--dsh-frame-leading-clearance,0px) - 20px));display:flex;container-type:inline-size}.wSkVaW_titleCluster{flex:1;align-items:center;gap:10px;min-width:0;display:flex}.wSkVaW_headerLeading{flex:none;grid-area:1/1;align-items:center;gap:8px;display:flex}.wSkVaW_crumbs{white-space:nowrap;align-items:center;gap:4px;min-width:0;display:flex;overflow:hidden}.wSkVaW_crumbSeg{align-items:center;gap:4px;min-width:0;display:inline-flex}.wSkVaW_crumbSep{color:var(--dsw-alias-label-caption);font-size:14px;line-height:20px}.wSkVaW_crumb{max-width:220px;color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;cursor:pointer;background:0 0;border:none;border-radius:12px;padding:4px 8px;font-size:14px;line-height:20px;display:inline-block;overflow:hidden}.wSkVaW_crumbSubagent{font-size:12px;line-height:18px}button.wSkVaW_crumb:hover{background:var(--dsw-alias-interactive-bg-hover)}.wSkVaW_crumbCurrent{color:var(--dsw-alias-label-primary);cursor:default;font-weight:500}.wSkVaW_headerActions{flex:none;align-items:center;gap:8px;display:flex}.wSkVaW_headerUtilities{flex:none;align-items:center;gap:8px;margin-left:20px;display:flex}.wSkVaW_headerUtilities:empty{display:none}.wSkVaW_headerCorner{flex:none;align-items:center;margin-left:8px;margin-right:-16px;display:flex}.wSkVaW_headerCorner:empty{display:none}.wSkVaW_tabs{z-index:1;grid-column:1/-1;gap:36px;margin-top:10px;padding-left:8px;display:flex;position:relative}.wSkVaW_tab{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;padding:0 0 9px;font-size:13px;font-weight:500;line-height:16px;position:relative}.wSkVaW_tab:after{content:\"\";background:0 0;border-radius:2px;height:2px;position:absolute;bottom:-1px;left:0;right:0}.wSkVaW_tabActive{color:var(--dsw-alias-state-business-primary)}.wSkVaW_tabActive:after{background:var(--dsw-alias-state-business-primary)}.wSkVaW_viewArea{flex-direction:column;flex:1;min-height:0;display:flex}.wSkVaW_widthHandle{z-index:0;width:min(10px, calc((100% - var(--dsh-chat-content-width)) / 2 - 24px - 24px));cursor:col-resize;position:absolute;top:0;bottom:0}.wSkVaW_widthHandle[data-side=left]{right:calc(50% + var(--dsh-chat-content-width) / 2 + 24px)}.wSkVaW_widthHandle[data-side=right]{left:calc(50% + var(--dsh-chat-content-width) / 2 + 24px)}.wSkVaW_widthHandle:after{content:\"\";background:linear-gradient(to bottom, transparent calc(var(--dsh-width-handle-pointer-y,50%) - 36px), var(--dsw-alias-scrollbar-bg-l1) calc(var(--dsh-width-handle-pointer-y,50%) - 8px), var(--dsw-alias-scrollbar-bg-l1) calc(var(--dsh-width-handle-pointer-y,50%) + 8px), transparent calc(var(--dsh-width-handle-pointer-y,50%) + 36px));opacity:0;pointer-events:none;border-radius:2px;width:2px;position:absolute;top:0;bottom:0}.wSkVaW_widthHandle[data-side=left]:after{right:4px}.wSkVaW_widthHandle[data-side=right]:after{left:4px}.wSkVaW_widthHandle:hover:after,.wSkVaW_widthHandle[data-dragging]:after{opacity:1}.wSkVaW_widthHandle[data-dragging]{z-index:8}.wSkVaW_root:has([data-conversation-composer-overlay]) .wSkVaW_widthHandle{display:none}.wSkVaW_composerStack{--dsh-composer-stack-gap:6px;gap:var(--dsh-composer-stack-gap);flex-direction:column;display:flex}.wSkVaW_composerSeat{--dsh-composer-text-max-height:336px;flex-direction:column;flex:none;display:flex}.wSkVaW_root[data-phase=active]{overflow:hidden}.wSkVaW_root[data-phase=active] .wSkVaW_header{flex:none}.wSkVaW_body{--dsh-chat-content-width:var(--dsh-chat-user-width,clamp(680px, calc(var(--dsh-conversation-column-width,0px) * .64), 920px));--dsh-composer-card-max-width:calc(var(--dsh-chat-content-width) + 32px);--dsh-composer-side-clearance:16px;--dsh-composer-dock-inset:8px;flex-direction:column;flex:1;min-height:0;display:flex;position:relative}.wSkVaW_embeddedBody{--dsh-chat-content-width:min(calc(100% - 32px), 920px);--dsh-composer-card-max-width:min(calc(100% - 16px), 952px);--dsh-composer-side-clearance:8px;--dsh-composer-dock-inset:8px;overflow:hidden}.wSkVaW_scrollBody{scrollbar-gutter:stable;flex-direction:column;flex:1;min-height:0;margin-right:2px;display:flex;overflow-y:auto}.wSkVaW_scrollBody::-webkit-scrollbar-track{margin:2px}.wSkVaW_root[data-phase=active] .wSkVaW_viewArea,.wSkVaW_embeddedBody[data-content-phase=active] .wSkVaW_viewArea{flex:1 0 auto;min-height:auto}.wSkVaW_root[data-phase=active] .wSkVaW_composerSeat,.wSkVaW_embeddedBody[data-content-phase=active] .wSkVaW_composerSeat{z-index:7;background:linear-gradient(180deg, color-mix(in srgb, var(--dsw-alias-bg-base) 0%, transparent) 0px, var(--dsw-alias-bg-base) 36px);position:sticky;bottom:0}.wSkVaW_root[data-phase=active] .wSkVaW_composerSeat:has([data-trigger-menu]){z-index:9}.wSkVaW_scrollBody:has([data-conversation-composer-overlay]){scrollbar-gutter:auto;position:relative;overflow:hidden auto}.wSkVaW_scrollBody:has([data-conversation-composer-overlay])>[data-slot=conversation\\.session]>.wSkVaW_viewArea{flex:1 1 0;min-height:0;overflow:hidden}.wSkVaW_scrollBody:has([data-conversation-composer-overlay])>.wSkVaW_composerSeat{right:var(--dsh-scrollbar-width);position:absolute;bottom:0;left:0}.wSkVaW_composerHero{width:min(calc(var(--dsh-composer-card-max-width) + 2 * var(--dsh-composer-side-clearance)), 100%);z-index:1;align-self:center;gap:8px;padding-bottom:32px}.wSkVaW_heroWorkspaceRow{align-items:center;gap:2px;min-width:0;margin-top:4px;padding:0 16px 0 20px;display:flex}.wSkVaW_root[data-phase=hero] .wSkVaW_scrollBody,.wSkVaW_embeddedBody[data-content-phase=hero] .wSkVaW_scrollBody{justify-content:center;overflow-y:auto}.wSkVaW_root[data-phase=settling] .wSkVaW_composerSeat,.wSkVaW_embeddedBody[data-content-phase=settling] .wSkVaW_composerSeat{visibility:hidden}";
|
|
15624
15667
|
const tagId$4 = "@deepseek-ai/dsh-client-ui-conversation/ConversationRoot.module.css";
|
|
15625
15668
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
|
|
15626
15669
|
const tag = document.createElement("style");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { SessionEventLike } from '@deepseek-ai/dsh-api-session-controller/client';
|
|
2
2
|
import type { SessionEvent } from '@deepseek-ai/dsh-session/types';
|
|
3
3
|
import type { ConversationGroupData, ConversationGroupedView, ConversationGroupInput } from './groups.ts';
|
|
4
|
-
/** Definition-local identity
|
|
4
|
+
/** Definition-local identity; start permits initialization when no earlier start is present. */
|
|
5
5
|
export interface ConversationMatchResult {
|
|
6
6
|
readonly id: string;
|
|
7
7
|
readonly role: 'start' | 'update';
|
|
@@ -101,8 +101,8 @@ interface ConversationMatchOf<Event extends SessionEventLike, Role extends Conve
|
|
|
101
101
|
readonly role: Role;
|
|
102
102
|
readonly location: ConversationLocation;
|
|
103
103
|
}
|
|
104
|
-
/**
|
|
105
|
-
export type ConversationStartMatch = ConversationMatchOf<
|
|
104
|
+
/** A durable or transient event that can initialize its Context. */
|
|
105
|
+
export type ConversationStartMatch = ConversationMatchOf<SessionEventLike, 'start'>;
|
|
106
106
|
/** One event accepted by a Definition, with its lifecycle role and resolved Location. */
|
|
107
107
|
export type ConversationMatch = ConversationStartMatch | ConversationMatchOf<SessionEventLike, 'update'>;
|
|
108
108
|
/** Target-neutral identity returned by a business Definition. */
|
|
@@ -172,7 +172,7 @@ export interface ConversationNodeDefinition<State = unknown> {
|
|
|
172
172
|
*/
|
|
173
173
|
match(event: SessionEventLike): ConversationMatchResult | null;
|
|
174
174
|
/**
|
|
175
|
-
* Create State from the
|
|
175
|
+
* Create State from the earliest currently loaded start Match.
|
|
176
176
|
* @param context - complete evidence currently collected for the Context.
|
|
177
177
|
* @param match - the start Match.
|
|
178
178
|
* @param reader - strictly-backward read-only Context lookup.
|
|
@@ -180,9 +180,9 @@ export interface ConversationNodeDefinition<State = unknown> {
|
|
|
180
180
|
*/
|
|
181
181
|
start(context: ConversationNodeContext<State>, match: ConversationStartMatch, reader: ConversationContextReader): State;
|
|
182
182
|
/**
|
|
183
|
-
* Apply
|
|
183
|
+
* Apply a later Match, including another event marked start.
|
|
184
184
|
* @param context - Context with its current State.
|
|
185
|
-
* @param match -
|
|
185
|
+
* @param match - subsequent Match in ascending event order.
|
|
186
186
|
* @returns the State adopted by the engine.
|
|
187
187
|
*/
|
|
188
188
|
update(context: ConversationNodeContext<State> & {
|
|
@@ -244,21 +244,31 @@ export interface CommandNode {
|
|
|
244
244
|
}
|
|
245
245
|
/** Finalized conversation node union (kind discriminates; seq is the React key). */
|
|
246
246
|
export type ConversationNode = UserMessageNode | AssistantMessageNode | SteeringMessageNode | ContextMessageNode | ModelRetryNode | TurnErrorNode | TurnMaxTokensNode | ToolResultNode | CommandNode | CompactionSummaryNode | UnknownSurfaceNode;
|
|
247
|
-
/**
|
|
248
|
-
|
|
247
|
+
/** Identity and placement shared by tool preparation and dispatch. */
|
|
248
|
+
interface ToolCallHead {
|
|
249
249
|
callId: string;
|
|
250
250
|
/** Parent Tool call for a PTC dispatch start; absent on a root Session call. */
|
|
251
251
|
parentCallId?: string;
|
|
252
252
|
name: string;
|
|
253
|
-
argsRaw: string;
|
|
254
253
|
turn: number;
|
|
255
254
|
step: number;
|
|
256
|
-
/** Unix epoch ms when
|
|
255
|
+
/** Unix epoch ms when this stage began. */
|
|
257
256
|
time: number;
|
|
258
257
|
/** Child calls owned by this call, in dispatch order. */
|
|
259
258
|
subCalls: readonly ToolCallBlock[];
|
|
260
259
|
}
|
|
261
|
-
/**
|
|
260
|
+
/** A named model call whose arguments are not yet available to tool views. */
|
|
261
|
+
export interface PreparingToolCall extends ToolCallHead {
|
|
262
|
+
readonly phase: 'preparing';
|
|
263
|
+
}
|
|
264
|
+
/** A dispatched tool call with complete arguments and no result yet. */
|
|
265
|
+
export interface StartedToolCall extends ToolCallHead {
|
|
266
|
+
readonly phase: 'start';
|
|
267
|
+
readonly argsRaw: string;
|
|
268
|
+
}
|
|
269
|
+
/** A tool still preparing or awaiting its result. */
|
|
270
|
+
export type RunningToolCall = PreparingToolCall | StartedToolCall;
|
|
271
|
+
/** One preparing, dispatched, or settled call, recursively owning its child calls. */
|
|
262
272
|
export type ToolCallBlock = RunningToolCall | ToolResultNode;
|
|
263
273
|
/** In-progress assistant output (chunk accumulator product). */
|
|
264
274
|
export interface PartialAssistant {
|
|
@@ -67,6 +67,8 @@ export declare class ConversationNodeAssembler implements ConversationViewSnapsh
|
|
|
67
67
|
append(record: SessionEventLikeEntry): ConversationPublication;
|
|
68
68
|
/**
|
|
69
69
|
* Retire one Assistant attempt's transient matches and apply its optional durable settlement.
|
|
70
|
+
* Empty Contexts retain their keys and published nodes until the loaded window is rebuilt;
|
|
71
|
+
* Definitions may hide those nodes when no start remains instead of withdrawing their identities.
|
|
70
72
|
* @param attemptId - process-local attempt whose transient presentation ended.
|
|
71
73
|
* @param entry - durable message or attempt event committed for the stream.
|
|
72
74
|
* @returns highest requested publication cadence.
|
|
@@ -117,6 +119,7 @@ export declare class ConversationNodeAssembler implements ConversationViewSnapsh
|
|
|
117
119
|
private acceptMatch;
|
|
118
120
|
private applyPendingMatches;
|
|
119
121
|
private replayContexts;
|
|
122
|
+
private refreshStarts;
|
|
120
123
|
private replayContext;
|
|
121
124
|
private indexTargetContext;
|
|
122
125
|
private markDirty;
|
|
@@ -10,7 +10,7 @@ export type { IConversation } from './service.ts';
|
|
|
10
10
|
export type { ConversationContextReader, ConversationLocation, ConversationLocationData, ConversationLocationDataScope, ConversationLocationDataSource, ConversationLocationDataStore, ConversationMatch, ConversationMatchResult, ConversationNodeContext, ConversationNodeDefinition, ConversationPreviousContext, ConversationPublication, ConversationStartMatch, ConversationStepDataMap, ConversationTimelineSnapshot, ConversationTurnDataMap, ConversationViewBuilder, ConversationViewDefinition, ConversationViewNode, ConversationViewSnapshotMap, ConversationViewSnapshotStore, StepLocation, TurnLocation, } from './contract/conversation.ts';
|
|
11
11
|
export { EMPTY_CONVERSATION_SNAPSHOT, conversationPhase } from './contract/snapshot.ts';
|
|
12
12
|
export type { ConversationPhase, ConversationSnapshot, } from './contract/snapshot.ts';
|
|
13
|
-
export type { AssistantBlock, AssistantMessageNode, AssistantProviderMetadataView, AssistantRequestConfig, AssistantTiming, CommandNode, CompactionSummaryNode, ContextMessageNode, ConversationNode, ModelRetryNode, PartialAssistant, RunningToolCall, SteeringMessageNode, TodoItem, ToolCallBlock, ToolResultNode, TurnErrorNode, TurnMaxTokensNode, UnknownSurfaceNode, UserMessageNode, } from './contract/records.ts';
|
|
13
|
+
export type { AssistantBlock, AssistantMessageNode, AssistantProviderMetadataView, AssistantRequestConfig, AssistantTiming, CommandNode, CompactionSummaryNode, ContextMessageNode, ConversationNode, ModelRetryNode, PartialAssistant, PreparingToolCall, RunningToolCall, StartedToolCall, SteeringMessageNode, TodoItem, ToolCallBlock, ToolResultNode, TurnErrorNode, TurnMaxTokensNode, UnknownSurfaceNode, UserMessageNode, } from './contract/records.ts';
|
|
14
14
|
export type { ContextProducerView, ContextRole, KnownContextForm, } from './contract/context-producer.ts';
|
|
15
15
|
export type { ConversationPromptSnapshot, RequestInspectionSnapshot, RequestPromptChange, RequestPromptInspection, RequestPromptInspector, RequestView, SystemPromptNode, } from './contract/request-inspection.ts';
|
|
16
16
|
export { inspectRequestPrompt } from './contract/request-inspection.ts';
|
|
@@ -79,6 +79,7 @@ export declare const zh: {
|
|
|
79
79
|
'tool.title.createGoal': string;
|
|
80
80
|
'tool.title.getGoal': string;
|
|
81
81
|
'tool.title.updateGoal': string;
|
|
82
|
+
'tool.preparing.content': string;
|
|
82
83
|
'tool.title.createSchedule': string;
|
|
83
84
|
'tool.title.listSchedules': string;
|
|
84
85
|
'tool.title.deleteSchedule': string;
|
|
@@ -276,6 +277,7 @@ export declare const zh: {
|
|
|
276
277
|
'bash.failed': string;
|
|
277
278
|
'bash.stopped': string;
|
|
278
279
|
'row.running': string;
|
|
280
|
+
'row.preparing': string;
|
|
279
281
|
'row.failed': string;
|
|
280
282
|
'row.stopped': string;
|
|
281
283
|
'row.input': string;
|
|
@@ -301,8 +303,6 @@ export declare const zh: {
|
|
|
301
303
|
'tool.autoReviewRejected': string;
|
|
302
304
|
'tool.autoReviewNotExecuted': string;
|
|
303
305
|
'tool.autoReviewReasonFallback': string;
|
|
304
|
-
'diff.files.one': string;
|
|
305
|
-
'diff.files.other': string;
|
|
306
306
|
'diff.collapseAria': string;
|
|
307
307
|
'diff.expandAria': string;
|
|
308
308
|
'diff.expandRest': string;
|
|
@@ -431,6 +431,7 @@ export declare const en: {
|
|
|
431
431
|
'tool.title.createGoal': string;
|
|
432
432
|
'tool.title.getGoal': string;
|
|
433
433
|
'tool.title.updateGoal': string;
|
|
434
|
+
'tool.preparing.content': string;
|
|
434
435
|
'tool.title.createSchedule': string;
|
|
435
436
|
'tool.title.listSchedules': string;
|
|
436
437
|
'tool.title.deleteSchedule': string;
|
|
@@ -628,6 +629,7 @@ export declare const en: {
|
|
|
628
629
|
'bash.failed': string;
|
|
629
630
|
'bash.stopped': string;
|
|
630
631
|
'row.running': string;
|
|
632
|
+
'row.preparing': string;
|
|
631
633
|
'row.failed': string;
|
|
632
634
|
'row.stopped': string;
|
|
633
635
|
'row.input': string;
|
|
@@ -653,8 +655,6 @@ export declare const en: {
|
|
|
653
655
|
'tool.autoReviewRejected': string;
|
|
654
656
|
'tool.autoReviewNotExecuted': string;
|
|
655
657
|
'tool.autoReviewReasonFallback': string;
|
|
656
|
-
'diff.files.one': string;
|
|
657
|
-
'diff.files.other': string;
|
|
658
658
|
'diff.collapseAria': string;
|
|
659
659
|
'diff.expandAria': string;
|
|
660
660
|
'diff.expandRest': string;
|
|
@@ -14,7 +14,7 @@ export interface QueueDockInjected {
|
|
|
14
14
|
export type QueueDockProps = PropsRuntime<'conversation.input.dock'> & QueueDockInjected & PropsLocale<'conversation'>;
|
|
15
15
|
/**
|
|
16
16
|
* Queue strip: one item renders directly; multiple items default to a
|
|
17
|
-
* collapsible count header; an empty queue renders nothing. Local submissions
|
|
17
|
+
* collapsible count header; an empty queue renders nothing. Local queued submissions
|
|
18
18
|
* show sending status and disabled actions until their Host queue rows arrive.
|
|
19
19
|
*/
|
|
20
20
|
export declare function QueueDock({ useSession, useProjection, updateQueue, notify, loadImage, t }: QueueDockProps): import("react").JSX.Element | null;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-ui-conversation",
|
|
3
3
|
"description": "Target-neutral Conversation assembly, shell, composer, queue, and view navigation",
|
|
4
|
-
"version": "0.1.7-
|
|
4
|
+
"version": "0.1.7-rc.1",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
},
|
|
43
43
|
"license": "MIT",
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@deepseek-ai/schemastery": "
|
|
45
|
+
"@deepseek-ai/schemastery": "~3.18.4"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"@deepseek-ai/cordis": "
|
|
48
|
+
"@deepseek-ai/cordis": "~4.0.4"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/react": "~18.3.1",
|
|
@@ -60,38 +60,38 @@
|
|
|
60
60
|
"@lexical/text": "^0.49.0",
|
|
61
61
|
"@lexical/plain-text": "^0.49.0",
|
|
62
62
|
"@lexical/history": "^0.49.0",
|
|
63
|
-
"@deepseek-ai/
|
|
64
|
-
"@deepseek-ai/dsh-api-
|
|
65
|
-
"@deepseek-ai/dsh-api-
|
|
66
|
-
"@deepseek-ai/
|
|
67
|
-
"@deepseek-ai/dsh-attachment": "
|
|
68
|
-
"@deepseek-ai/dsh-client-locale": "
|
|
69
|
-
"@deepseek-ai/dsh-
|
|
70
|
-
"@deepseek-ai/dsh-client-
|
|
71
|
-
"@deepseek-ai/dsh-
|
|
72
|
-
"@deepseek-ai/dsh-client-
|
|
73
|
-
"@deepseek-ai/dsh-client-ui-
|
|
74
|
-
"@deepseek-ai/dsh-client-ui-
|
|
75
|
-
"@deepseek-ai/dsh-client-
|
|
76
|
-
"@deepseek-ai/dsh-client-ui-
|
|
77
|
-
"@deepseek-ai/dsh-client-ui-workspace": "
|
|
78
|
-
"@deepseek-ai/dsh-client-ui-slots": "
|
|
79
|
-
"@deepseek-ai/dsh-
|
|
80
|
-
"@deepseek-ai/dsh-
|
|
81
|
-
"@deepseek-ai/dsh-
|
|
82
|
-
"@deepseek-ai/dsh-llm
|
|
83
|
-
"@deepseek-ai/dsh-
|
|
84
|
-
"@deepseek-ai/dsh-
|
|
85
|
-
"@deepseek-ai/dsh-
|
|
86
|
-
"@deepseek-ai/dsh-
|
|
87
|
-
"@deepseek-ai/dsh-token-meter": "
|
|
88
|
-
"@deepseek-ai/dsh-
|
|
89
|
-
"@deepseek-ai/dsh-
|
|
90
|
-
"@deepseek-ai/dsh-workspace": "
|
|
91
|
-
"@deepseek-ai/dsh-
|
|
92
|
-
"@deepseek-ai/dsh-
|
|
93
|
-
"@deepseek-ai/dsh-
|
|
94
|
-
"@deepseek-ai/dsh-
|
|
63
|
+
"@deepseek-ai/cordis": "~4.0.4",
|
|
64
|
+
"@deepseek-ai/dsh-api-remotes": "0.1.7-rc.1",
|
|
65
|
+
"@deepseek-ai/dsh-api-session-controller": "0.1.7-rc.1",
|
|
66
|
+
"@deepseek-ai/dsh-api-workspace-controller": "0.1.7-rc.1",
|
|
67
|
+
"@deepseek-ai/dsh-attachment": "0.1.7-rc.1",
|
|
68
|
+
"@deepseek-ai/dsh-client-locale": "0.1.7-rc.1",
|
|
69
|
+
"@deepseek-ai/dsh-brand": "0.1.7-rc.1",
|
|
70
|
+
"@deepseek-ai/dsh-client-file-upload": "0.1.7-rc.1",
|
|
71
|
+
"@deepseek-ai/dsh-client-test-runtime": "0.1.7-rc.1",
|
|
72
|
+
"@deepseek-ai/dsh-client-ui-layout": "0.1.7-rc.1",
|
|
73
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.1",
|
|
74
|
+
"@deepseek-ai/dsh-client-ui-session": "0.1.7-rc.1",
|
|
75
|
+
"@deepseek-ai/dsh-client-store": "0.1.7-rc.1",
|
|
76
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.1",
|
|
77
|
+
"@deepseek-ai/dsh-client-ui-workspace": "0.1.7-rc.1",
|
|
78
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.1",
|
|
79
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.7-rc.1",
|
|
80
|
+
"@deepseek-ai/dsh-commands": "0.1.7-rc.1",
|
|
81
|
+
"@deepseek-ai/dsh-goal": "0.1.7-rc.1",
|
|
82
|
+
"@deepseek-ai/dsh-llm": "0.1.7-rc.1",
|
|
83
|
+
"@deepseek-ai/dsh-llm-retry": "0.1.7-rc.1",
|
|
84
|
+
"@deepseek-ai/dsh-plan-mode": "0.1.7-rc.1",
|
|
85
|
+
"@deepseek-ai/dsh-util-values": "0.1.7-rc.1",
|
|
86
|
+
"@deepseek-ai/dsh-tool-todo": "0.1.7-rc.1",
|
|
87
|
+
"@deepseek-ai/dsh-token-meter": "0.1.7-rc.1",
|
|
88
|
+
"@deepseek-ai/dsh-util-crypto": "0.1.7-rc.1",
|
|
89
|
+
"@deepseek-ai/dsh-file-reference": "0.1.7-rc.1",
|
|
90
|
+
"@deepseek-ai/dsh-util-workspace-path": "0.1.7-rc.1",
|
|
91
|
+
"@deepseek-ai/dsh-agent": "0.1.7-rc.1",
|
|
92
|
+
"@deepseek-ai/dsh-settings": "0.1.7-rc.1",
|
|
93
|
+
"@deepseek-ai/dsh-session": "0.1.7-rc.1",
|
|
94
|
+
"@deepseek-ai/dsh-workspace": "0.1.7-rc.1"
|
|
95
95
|
},
|
|
96
96
|
"files": [
|
|
97
97
|
"lib/index.js",
|