@deepseek-ai/dsh-client-ui-conversation 0.1.7-alpha.2 → 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 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: 4823aa0a1ba5975c4efc8b6bdddd7ca8c57c068f
6
- README.zh.md: 5ef8a1b6621bf8bab7e98cb18722a9aedda29101
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. Every Definition uses the same `match` and `update` methods for both event forms, while `start` receives only a durable event and the assembler rejects a transient start. 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 replays the affected Contexts and dependents without replacing unrelated target 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`.
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
 
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 则可以携带任一种。两种事件都使用 Definition 的同一组 `match` `update` 方法,`start` 只接收持久 event,assembler 会拒绝 transient start。不消费 Assistant delta 的 Definition 对 `assistant/live-chunk` 返回 `null`。replace window 或 revision 断档从完整已加载窗口重建;连续 revision 的 append、prepend 与 Assistant settlement 使用增量组装。settlement 只删除具名 attempt 的 transient match,应用可选持久 entry,并重放受影响的 Context 及其 dependent,不替换无关 target nodeassembler 拥有 Context 匹配、Turn/Step location、target node 物化、target activity 和稳定 target source。`ConversationSnapshot` 只包含与 target 无关的 View 与 active-target 事实;Session lifecycle 状态仍属于 `SessionSnapshot`。
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
 
package/lib/client.js CHANGED
@@ -1860,15 +1860,7 @@ window.__ModuleLoader__.load({
1860
1860
  }
1861
1861
  return merged;
1862
1862
  }
1863
- function conversationMatch(key, input, role, location) {
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(key, input, role, this.locationIndex.locationOf(input.event));
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 match = conversationMatch(key, input, role, this.locationIndex.locationOf(input.event));
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 (role === "start" && context.matches.length > 0) throw new Error(`conversation Context ${key} received an update before its start Match`);
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 (match.role === "start") this.replayContext(context);
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 || match.role !== "update") continue;
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": "运行 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 插件",
@@ -14803,6 +14807,7 @@ window.__ModuleLoader__.load({
14803
14807
  "tool.title.createGoal": "Create goal",
14804
14808
  "tool.title.getGoal": "View goal",
14805
14809
  "tool.title.updateGoal": "Update goal",
14810
+ "tool.preparing.content": "Preparing content {kilobytes}KB",
14806
14811
  "tool.title.createSchedule": "Create reminder",
14807
14812
  "tool.title.listSchedules": "List reminders",
14808
14813
  "tool.title.deleteSchedule": "Delete reminder",
@@ -14848,15 +14853,15 @@ window.__ModuleLoader__.load({
14848
14853
  "tool.title.queryRuntime": "Query runtime",
14849
14854
  "tool.title.inspectPlugins": "Inspect plugins",
14850
14855
  "tool.title.workflow": "Run workflow",
14851
- "tool.title.ralph": "Run Ralph",
14856
+ "tool.title.ralph": "Run ralph loop",
14852
14857
  "tool.title.readEvent": "Read event",
14853
14858
  "tool.title.searchEvents": "Search events",
14854
14859
  "tool.title.traceEvent": "Trace event",
14855
14860
  "tool.title.searchSessions": "Search sessions",
14856
14861
  "tool.title.traceSession": "Trace session",
14857
14862
  "tool.title.listModels": "List models",
14858
- "tool.title.subagent": "Delegate task",
14859
- "tool.title.listAgents": "List agents",
14863
+ "tool.title.subagent": "Create subagent",
14864
+ "tool.title.listAgents": "List subagents",
14860
14865
  "tool.title.sendMessage": "Send message",
14861
14866
  "tool.title.interruptAgent": "Interrupt agent",
14862
14867
  "tool.title.listJobs": "List background jobs",
@@ -14877,7 +14882,7 @@ window.__ModuleLoader__.load({
14877
14882
  "tool.title.getTeamTask": "Read team task",
14878
14883
  "tool.title.updateTeamTask": "Update team task",
14879
14884
  "tool.title.listTeamTasks": "List team tasks",
14880
- "tool.title.waitAgent": "Wait for teammates",
14885
+ "tool.title.waitAgent": "Wait for subagent",
14881
14886
  "detail.recordedResult": "Recorded result",
14882
14887
  "detail.empty": "No results",
14883
14888
  "detail.none": "None",
@@ -14961,8 +14966,8 @@ window.__ModuleLoader__.load({
14961
14966
  "detail.receipt.signal": "Signal delivered",
14962
14967
  "detail.receipt.closed": "Closed",
14963
14968
  "detail.receipt.closing": "Closing",
14964
- "detail.wait.noProgress": "No active teammates",
14965
- "detail.wait.title": "Teammate activity",
14969
+ "detail.wait.noProgress": "No active subagents",
14970
+ "detail.wait.title": "Subagent activity",
14966
14971
  "detail.wait.timeout": "Wait timed out",
14967
14972
  "detail.wait.changed": "Change detected",
14968
14973
  "detail.agent.reply": "Agent response",
@@ -15000,6 +15005,7 @@ window.__ModuleLoader__.load({
15000
15005
  "bash.failed": "Failed",
15001
15006
  "bash.stopped": "Stopped",
15002
15007
  "row.running": "Running",
15008
+ "row.preparing": "Preparing tool call",
15003
15009
  "row.failed": "Failed",
15004
15010
  "row.stopped": "Stopped",
15005
15011
  "row.input": "IN",
@@ -15012,7 +15018,7 @@ window.__ModuleLoader__.load({
15012
15018
  "tool.title.edit": "Edit",
15013
15019
  "tool.title.code": "Code",
15014
15020
  "tool.title.generic": "Tool call",
15015
- "tool.title.inspect": "Inspect",
15021
+ "tool.title.inspect": "Query Cordis environment",
15016
15022
  "tool.title.runCordis": "Run Cordis Plugin",
15017
15023
  "tool.title.stopCordis": "Stop Cordis Plugin",
15018
15024
  "tool.title.removeCordis": "Remove Cordis Plugin",
@@ -15372,6 +15378,7 @@ window.__ModuleLoader__.load({
15372
15378
  queueMutable && (0, react_jsx_runtime.jsx)("div", {
15373
15379
  className: QueueDock_module_css_default.actions,
15374
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,
15375
15382
  label: t("queue.save"),
15376
15383
  side: "bottom",
15377
15384
  delayMs: 500,
@@ -15386,6 +15393,7 @@ window.__ModuleLoader__.load({
15386
15393
  children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutlineRegular, { size: 14 })
15387
15394
  })
15388
15395
  }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
15396
+ portal: true,
15389
15397
  label: t("queue.cancelEdit"),
15390
15398
  side: "bottom",
15391
15399
  delayMs: 500,
@@ -15401,6 +15409,7 @@ window.__ModuleLoader__.load({
15401
15409
  })
15402
15410
  })] }) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
15403
15411
  (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
15412
+ portal: true,
15404
15413
  label: t("queue.edit"),
15405
15414
  side: "bottom",
15406
15415
  delayMs: 500,
@@ -15421,6 +15430,7 @@ window.__ModuleLoader__.load({
15421
15430
  })
15422
15431
  }),
15423
15432
  (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
15433
+ portal: true,
15424
15434
  label: t("queue.remove"),
15425
15435
  side: "bottom",
15426
15436
  delayMs: 500,
@@ -15436,6 +15446,7 @@ window.__ModuleLoader__.load({
15436
15446
  })
15437
15447
  }),
15438
15448
  (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
15449
+ portal: true,
15439
15450
  label: t("queue.steer"),
15440
15451
  side: "bottom",
15441
15452
  delayMs: 500,
@@ -15652,7 +15663,7 @@ window.__ModuleLoader__.load({
15652
15663
  }
15653
15664
  //#endregion
15654
15665
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-conversation/src/client/skeleton/ConversationRoot.module.css.mjs
15655
- 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}";
15656
15667
  const tagId$4 = "@deepseek-ai/dsh-client-ui-conversation/ConversationRoot.module.css";
15657
15668
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
15658
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 and lifecycle role extracted from one event. */
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
- /** One scalar event accepted as a Context's unique start. */
105
- export type ConversationStartMatch = ConversationMatchOf<SessionEvent, 'start'>;
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 unique start Match.
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 one post-start update Match.
183
+ * Apply a later Match, including another event marked start.
184
184
  * @param context - Context with its current State.
185
- * @param match - update Match in ascending log order.
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
- /** In-flight tool card material: tool/call seen, tool/result not yet. */
248
- export interface RunningToolCall {
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 the tool/call event was logged. */
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
- /** One running or settled call, recursively owning its child calls. */
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;
@@ -429,6 +431,7 @@ export declare const en: {
429
431
  'tool.title.createGoal': string;
430
432
  'tool.title.getGoal': string;
431
433
  'tool.title.updateGoal': string;
434
+ 'tool.preparing.content': string;
432
435
  'tool.title.createSchedule': string;
433
436
  'tool.title.listSchedules': string;
434
437
  'tool.title.deleteSchedule': string;
@@ -626,6 +629,7 @@ export declare const en: {
626
629
  'bash.failed': string;
627
630
  'bash.stopped': string;
628
631
  'row.running': string;
632
+ 'row.preparing': string;
629
633
  'row.failed': string;
630
634
  'row.stopped': string;
631
635
  'row.input': string;
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-alpha.2",
4
+ "version": "0.1.7-rc.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -61,37 +61,37 @@
61
61
  "@lexical/plain-text": "^0.49.0",
62
62
  "@lexical/history": "^0.49.0",
63
63
  "@deepseek-ai/cordis": "~4.0.4",
64
- "@deepseek-ai/dsh-api-remotes": "0.1.7-alpha.2",
65
- "@deepseek-ai/dsh-api-workspace-controller": "0.1.7-alpha.2",
66
- "@deepseek-ai/dsh-attachment": "0.1.7-alpha.2",
67
- "@deepseek-ai/dsh-api-session-controller": "0.1.7-alpha.2",
68
- "@deepseek-ai/dsh-brand": "0.1.7-alpha.2",
69
- "@deepseek-ai/dsh-client-locale": "0.1.7-alpha.2",
70
- "@deepseek-ai/dsh-client-file-upload": "0.1.7-alpha.2",
71
- "@deepseek-ai/dsh-client-store": "0.1.7-alpha.2",
72
- "@deepseek-ai/dsh-client-ui-layout": "0.1.7-alpha.2",
73
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-alpha.2",
74
- "@deepseek-ai/dsh-client-ui-renderer": "0.1.7-alpha.2",
75
- "@deepseek-ai/dsh-client-ui-session": "0.1.7-alpha.2",
76
- "@deepseek-ai/dsh-client-test-runtime": "0.1.7-alpha.2",
77
- "@deepseek-ai/dsh-client-ui-settings": "0.1.7-alpha.2",
78
- "@deepseek-ai/dsh-client-ui-workspace": "0.1.7-alpha.2",
79
- "@deepseek-ai/dsh-client-ui-slots": "0.1.7-alpha.2",
80
- "@deepseek-ai/dsh-commands": "0.1.7-alpha.2",
81
- "@deepseek-ai/dsh-goal": "0.1.7-alpha.2",
82
- "@deepseek-ai/dsh-llm": "0.1.7-alpha.2",
83
- "@deepseek-ai/dsh-plan-mode": "0.1.7-alpha.2",
84
- "@deepseek-ai/dsh-session": "0.1.7-alpha.2",
85
- "@deepseek-ai/dsh-util-values": "0.1.7-alpha.2",
86
- "@deepseek-ai/dsh-token-meter": "0.1.7-alpha.2",
87
- "@deepseek-ai/dsh-tool-todo": "0.1.7-alpha.2",
88
- "@deepseek-ai/dsh-util-crypto": "0.1.7-alpha.2",
89
- "@deepseek-ai/dsh-workspace": "0.1.7-alpha.2",
90
- "@deepseek-ai/dsh-file-reference": "0.1.7-alpha.2",
91
- "@deepseek-ai/dsh-util-workspace-path": "0.1.7-alpha.2",
92
- "@deepseek-ai/dsh-agent": "0.1.7-alpha.2",
93
- "@deepseek-ai/dsh-settings": "0.1.7-alpha.2",
94
- "@deepseek-ai/dsh-llm-retry": "0.1.7-alpha.2"
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",