@deepseek-ai/dsh-client-ui-tool 0.1.5-rc.2 → 0.1.6-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +9 -4
- package/README.zh.md +13 -8
- package/lib/client.js +223 -186
- package/lib/types/client/tool/models/auto-review-denial.d.ts +21 -0
- package/lib/types/client/tool/models/diff-card-model.d.ts +2 -10
- package/lib/types/client/tool/models/terminal-card-model.d.ts +1 -1
- package/lib/types/client/tool/models/tool-call-model.d.ts +7 -0
- package/package.json +22 -22
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-tool/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 15dffa634660a5cf94081452481399821d09b25b
|
|
6
|
+
README.zh.md: 6f01658e5fea4fefca9eded114971d3e88a13148
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
|
|
|
9
9
|
|
|
10
10
|
## Summary
|
|
11
11
|
|
|
12
|
-
`dsh-client-ui-tool` is the client Tool presentation plugin of the dsh web client: it renders every tool call in the conversation. `ui-conversation` dispatches each ordered `tool-call` Conversation Node through the matching key of `conversation.chat.node`; this package renders its root and
|
|
12
|
+
`dsh-client-ui-tool` is the client Tool presentation plugin of the dsh web client: it renders every tool call in the conversation. `ui-conversation` dispatches each ordered `tool-call` Conversation Node through the matching key of `conversation.chat.node`; this package renders its root and PTC dispatch children, then dispatches every atomic call through the keyed `tool.call.toolview` slot. Unregistered Tool names use the generic card. Business UI packages register only their wire Tool names and atomic views — they do not pair Session events, rebuild the transcript, or own root/subcall topology, because the Runtime remains authoritative for call/result pairing, lifecycle, and recursive `subCalls` projection.
|
|
13
13
|
|
|
14
14
|
## Table of Contents
|
|
15
15
|
|
|
@@ -39,11 +39,11 @@ ctx.slots.inject('tool.call.toolview', () =>
|
|
|
39
39
|
}, BusinessToolRow))
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
The owner payload is `ToolCallOwnerProps`: `callId`, `toolName`, the frozen `block`, optional `cwd` and `home`, the session-authorized `loadImage` loader (for a view whose result carries durable images), and plain `openFile`/`inspect` callbacks. A
|
|
42
|
+
The owner payload is `ToolCallOwnerProps`: `callId`, `toolName`, the frozen `block`, optional `cwd` and `home`, the session-authorized `loadImage` loader (for a view whose result carries durable images), and plain `openFile`/`inspect` callbacks. A PTC dispatch block retains its event's `parentCallId`; a root Session call has no such field, so descendants route through the same keyed dispatch — a registered view such as `read_image` renders its card there, and unregistered descendants keep the generic flattened form. Path summaries relativize to the Session cwd first, then replace a leftover POSIX Host home with `~`; `filePath` and Host open keep the authored filesystem path. The registration receives the normal Session slot runtime share but no React node or Runtime service.
|
|
43
43
|
|
|
44
44
|
### Built-in views
|
|
45
45
|
|
|
46
|
-
This package owns the generic fallback and the built-in shell/pwsh, read, read_image, write/edit, running `str_replace_editor` `create`/`str_replace`, grep/glob, web, todo, question, and
|
|
46
|
+
This package owns the generic fallback and the built-in shell/pwsh, read, read_image, write/edit, running `str_replace_editor` `create`/`str_replace`, grep/glob, web, todo, question, and PTC dispatch presentations. Structured cards derive directly from first-party raw event fields; Host `presentCall` and `presentResult` values never enter the Client. Running and settled foreground standard `bash`/`pwsh` and `terminal_send` calls use terminal cards at the root and in PTC dispatch children, subject to the same argument, result, and error checks. Persistent `bash`/`pwsh` calls use terminal cards only while running. Shell output ending in a recognized spill-policy notice uses expandable generic output in shell rows and generic output in Details; a displaced or omitted exit marker cannot establish success. Settled persistent-shell results stay generic because reset and partial-output diagnostics do not always describe one process exit status; root persistent results are expandable, while background acknowledgements remain collapsed. A native or PTC dispatch failure carrying `AUTO_REVIEW_DENIED` shows the Auto review verdict in its collapsed row and one normalized not-executed reason when expanded; a missing or whitespace-only reason uses localized fallback text. A successful question row pairs call questions with result answers by their stable ids and shows readable question/answer lines when expanded. A cancelled or interrupted row shows its verdict and original questions without inventing answers. Unsupported, malformed, or ambiguous inputs fall back to flattened Tool input/result text. `ui-skill` demonstrates a business-owned registration for `skill`.
|
|
47
47
|
|
|
48
48
|
-----
|
|
49
49
|
|
|
@@ -62,7 +62,11 @@ The package realizes one dispatch rule: atomic Tool views are keyed by wire Tool
|
|
|
62
62
|
### Cards
|
|
63
63
|
|
|
64
64
|
|
|
65
|
-
Every card is read in place in the call tree; there is no second, full-height presentation of a selected call. Row renderers share one pure card model for each terminal, read, diff, search, and web card, and the image card's gallery renders through the tool-owned `tool.call.images` slot. These models validate raw call arguments, result content, failure state, persisted metadata,
|
|
65
|
+
Every card is read in place in the call tree; there is no second, full-height presentation of a selected call. Row renderers share one pure card model for each terminal, read, diff, search, and web card, and the image card's gallery renders through the tool-owned `tool.call.images` slot. These models validate raw call arguments, result content, failure state, persisted metadata, PTC dispatch `parentCallId`, and Session path facts. Unsupported or malformed inputs use flattened Tool result text. A file-path summary opens the file through the owner's `openFile`, which the chat view routes to the right Sidebar's text preview; `inspect` opens the trajectory view. Card-specific limits and fallback rules for the terminal, diff, read, search, and web cards remain in [the ui-primitives README](../ui-primitives/README.md); the image card's model in this package carries its own fallback rules.
|
|
66
|
+
|
|
67
|
+
Chat diff cards keep nine rows before folding, enough for a file header, one removed/added pair, and three context lines on either side. The collapsed row and expanded footer share the primitive's exact or coarse-replacement counts.
|
|
68
|
+
|
|
69
|
+
An Auto denial takes precedence over keyed specialized views. Its generic row preserves the call identity, omits raw arguments, and normalizes the stored reason only for display: trim surrounding whitespace and collapse line separators to spaces, with localized fallback for an empty result. Session and SDK error details keep the original reason.
|
|
66
70
|
|
|
67
71
|
The terminal model uses `hasSpillNotice` from the browser-safe `@deepseek-ai/dsh-spill-policy/notice` entry, not an independent UI pattern. The [spill-policy README](../../spill/spill-policy/README.md#shared-notice-ownership) owns notice formatting and recognition. This check conservatively selects generic output; matching text cannot authenticate its source, and replay leaves recorded result bytes untouched.
|
|
68
72
|
</details>
|
|
@@ -77,6 +81,7 @@ These pages cover the conversation host, the view slots, and the card models.
|
|
|
77
81
|
- [ui-conversation](../ui-conversation/README.md) — the chat surface dispatching `tool-call` nodes to this package.
|
|
78
82
|
- [ui-primitives](../ui-primitives/README.md) — the output card atoms the built-in views compose.
|
|
79
83
|
- [ui-skill](../ui-skill/README.md) — a business-owned registration for the `skill` tool.
|
|
84
|
+
- [Auto review](../../experimental/auto-review/README.md) — the structured denial identity and user-visible reason owner.
|
|
80
85
|
- [Conversation subsystem](../../../docs/subsystems/conversation.md) — how a business-owned feature registers a Conversation node.
|
|
81
86
|
- [Slot system standard](../../../.agents/notes/implemented/architecture/2026-07-22-slot-type-chain-implementation.md) — the composition model behind the keyed slot.
|
|
82
87
|
|
package/README.zh.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "dsh Web 客户端的 Client
|
|
2
|
+
description: "dsh Web 客户端的 Client 工具展示插件:完整调用树的组合、按工具名称键控的视图 slot,以及内置原子工具卡片。"
|
|
3
3
|
kind: "package-reference"
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -9,7 +9,7 @@ kind: "package-reference"
|
|
|
9
9
|
|
|
10
10
|
## 概述
|
|
11
11
|
|
|
12
|
-
`dsh-client-ui-tool` 是 dsh Web 客户端的 Client 工具展示插件:它渲染对话中的每一次工具调用。`ui-conversation` 通过 `conversation.chat.node` 的匹配 key 分发每个已排序的 `tool-call` Conversation Node;本包渲染其中的 root 及其
|
|
12
|
+
`dsh-client-ui-tool` 是 dsh Web 客户端的 Client 工具展示插件:它渲染对话中的每一次工具调用。`ui-conversation` 通过 `conversation.chat.node` 的匹配 key 分发每个已排序的 `tool-call` Conversation Node;本包渲染其中的 root 及其 PTC dispatch 子调用,并把每个原子调用通过 keyed slot `tool.call.toolview` 分发。没有注册的工具名称使用通用卡片。业务 UI 包只注册 wire 工具名称和原子视图——它们不配对会话事件、不重建 transcript(文本记录),也不拥有 root/subcall 拓扑,因为运行时仍对 call/result 配对、生命周期与递归 `subCalls` 投影拥有最终决定权。
|
|
13
13
|
|
|
14
14
|
## 目录
|
|
15
15
|
|
|
@@ -39,11 +39,11 @@ ctx.slots.inject('tool.call.toolview', () =>
|
|
|
39
39
|
}, BusinessToolRow))
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
owner 载荷为 `ToolCallOwnerProps`:`callId`、`toolName`、冻结的 `block`、可选 `cwd` 与 `home`、会话授权的 `loadImage` loader(供结果携带持久图像的视图使用),以及普通的 `openFile`/`inspect` 回调。
|
|
42
|
+
owner 载荷为 `ToolCallOwnerProps`:`callId`、`toolName`、冻结的 `block`、可选 `cwd` 与 `home`、会话授权的 `loadImage` loader(供结果携带持久图像的视图使用),以及普通的 `openFile`/`inspect` 回调。PTC dispatch 块保留事件的 `parentCallId`;根会话调用没有该字段,因此后代调用都走同一条按 key 分发路径:已注册视图的调用(如 `read_image`)也会在嵌套处渲染对应卡片,未注册的后代调用则保持通用压平形式。路径摘要先相对会话 cwd 缩短,再把剩余的 POSIX Host home 写成 `~`;`filePath` 与 Host 打开仍使用作者给出的文件系统路径。注册项会收到常规的会话 slot 运行时共享数据,但不会收到 React 节点或运行时服务。
|
|
43
43
|
|
|
44
44
|
### 内置视图
|
|
45
45
|
|
|
46
|
-
本包拥有 generic fallback,以及 shell/pwsh、read、read_image、write/edit
|
|
46
|
+
本包拥有 generic fallback,以及 shell/pwsh、read、read_image、write/edit、运行中的 `str_replace_editor` `create`/`str_replace`、grep/glob、web、todo、question 与 PTC dispatch 的内置展示。结构化卡片直接从第一方原始 event 字段派生;Host `presentCall` 与 `presentResult` 值不会进入 Client。运行中与已完成的前台标准 `bash`/`pwsh` 和 `terminal_send` 调用,无论位于根还是 PTC dispatch 子调用中,都在通过相同的参数、结果和错误检查后使用 terminal 卡片。持久 `bash`/`pwsh` 调用仅在运行中使用 terminal 卡片。以已识别的 spill 策略提示结尾的 shell 输出,在 shell 行中使用可展开的 generic 输出,在 Details 中使用 generic 输出;位置被改变或被省略的退出标记无法证明成功。已完成的持久 shell 结果保持 generic 展示,因为 reset 与部分输出诊断不一定描述单个进程的退出状态;根调用的持久 shell 结果可展开,后台启动回执则保持折叠。带有 `AUTO_REVIEW_DENIED` 的原生或 PTC dispatch 失败会在折叠行显示 Auto review 裁决,展开时显示一行归一化后的“未执行”原因;原因缺失或只有空白时使用本地化 fallback 文案。成功的问题行按稳定 id 配对调用中的问题与结果中的回答,展开后显示可读的问答行。已取消或已中断的问题行显示其裁决与原始问题,不虚构回答。不受支持、格式错误或含糊的输入回退为压平的工具输入/结果文本。`ui-skill` 展示了业务包自行拥有的 `skill` 注册项。
|
|
47
47
|
|
|
48
48
|
-----
|
|
49
49
|
|
|
@@ -62,9 +62,13 @@ owner 载荷为 `ToolCallOwnerProps`:`callId`、`toolName`、冻结的 `block`
|
|
|
62
62
|
### 卡片
|
|
63
63
|
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
每张卡片都直接在调用树中查看;选中调用后不会再显示第二个全高视图。行 renderer 为 terminal、read、diff、search 和 web 卡片各复用同一个纯 card model,image 卡片的图库经由工具自有 `tool.call.images` slot 渲染。这些 model 校验原始调用参数、结果内容、失败状态、持久 metadata、PTC dispatch 的 `parentCallId` 与会话路径信息。不受支持或格式错误的输入使用压平的工具结果文本。文件路径摘要经属主的 `openFile` 打开文件,chat 视图把它路由到右侧 Sidebar 的文本预览;`inspect` 打开轨迹视图。terminal、diff、read、search 与 web 卡片的上限与 fallback 规则仍由 [ui-primitives README](../ui-primitives/README.zh.md) 负责;image 卡片的 fallback 规则由本包内的 card model 自行承载。
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
Chat diff 卡片在折叠前保留九行,足以容纳文件标题、一对删除与新增行及两侧各三行上下文。折叠工具行与展开卡片底部采用原语一致的精确或粗粒度替换统计。
|
|
68
|
+
|
|
69
|
+
Auto 拒绝优先于按工具名选择的专门视图。其通用行保留调用身份、省略原始参数,并且只在显示时归一化存储的理由:去除首尾空白,把行分隔符折叠为空格,结果为空时使用本地化通用理由。Session 与 SDK 错误详情保留原始理由。
|
|
70
|
+
|
|
71
|
+
terminal model 使用浏览器安全入口 `@deepseek-ai/dsh-spill-policy/notice` 的 `hasSpillNotice`,而非独立的 UI 匹配规则。[spill-policy README](../../spill/spill-policy/README.zh.md#shared-notice-ownership) 负责提示文本的格式化与识别。该检查保守地选择通用输出;匹配的文本无法证明其来源,回放也不改变已记录的结果字节。
|
|
68
72
|
</details>
|
|
69
73
|
|
|
70
74
|
-----
|
|
@@ -77,6 +81,7 @@ terminal model 使用浏览器安全入口 `@deepseek-ai/dsh-spill-policy/notice
|
|
|
77
81
|
- [ui-conversation](../ui-conversation/README.zh.md)——把 `tool-call` 节点分派给本包的聊天界面。
|
|
78
82
|
- [ui-primitives](../ui-primitives/README.zh.md)——内置视图所拼装的输出卡片原子组件。
|
|
79
83
|
- [ui-skill](../ui-skill/README.zh.md)——`skill` 工具的业务自有注册。
|
|
84
|
+
- [Auto review](../../experimental/auto-review/README.zh.md)——结构化拒绝身份与用户可见原因的 owner。
|
|
80
85
|
- [Conversation 子系统](../../../docs/subsystems/conversation.zh.md)——业务自有功能如何注册 Conversation node。
|
|
81
86
|
- [slot 系统标准](../../../.agents/notes/implemented/architecture/2026-07-22-slot-type-chain-implementation.zh.md)——keyed slot 背后的组合模型。
|
|
82
87
|
|
|
@@ -100,7 +105,7 @@ terminal model 使用浏览器安全入口 `@deepseek-ai/dsh-spill-policy/notice
|
|
|
100
105
|
|
|
101
106
|
- **Host 不把 `run_code` 暴露为 PTC mode 程序 binding**:生产事件只产生一层分发;递归的运行时/UI 约定支持嵌套。
|
|
102
107
|
- **第一方工具视图集中在本包**:它们可以通过 keyed slot 独立迁移到各自所属的业务包。
|
|
103
|
-
- **工具文案复用 `ui-conversation` locale namespace**:工具标题、行 chrome 与无 Cordis 的 primitive label
|
|
108
|
+
- **工具文案复用 `ui-conversation` locale namespace**:工具标题、行 chrome 与无 Cordis 的 primitive label 使用该字典;展示转换器模型保留 locale key 或数据,而不是已渲染文案。
|
|
104
109
|
|
|
105
110
|
<a id="dev-note"></a>
|
|
106
111
|
### 开发备注
|
|
@@ -112,4 +117,4 @@ terminal model 使用浏览器安全入口 `@deepseek-ai/dsh-spill-policy/notice
|
|
|
112
117
|
|
|
113
118
|
</details>
|
|
114
119
|
|
|
115
|
-
**运行时不变式:**
|
|
120
|
+
**运行时不变式:** 不发布伴生入口。工具组合只存在于浏览器,不贡献事件或跨插件可变状态;slot 所有权由 ui-slots 校验。
|
package/lib/client.js
CHANGED
|
@@ -60,6 +60,193 @@ window.__ModuleLoader__.load({
|
|
|
60
60
|
return text;
|
|
61
61
|
}
|
|
62
62
|
//#endregion
|
|
63
|
+
//#region lib/types/client/tool/models/tool-call-model.js
|
|
64
|
+
/** Locale key per generic row variant. */
|
|
65
|
+
const VARIANT_TITLE_KEYS = {
|
|
66
|
+
search: "tool.title.search",
|
|
67
|
+
read: "tool.title.read",
|
|
68
|
+
bash: "tool.title.bash",
|
|
69
|
+
write: "tool.title.write",
|
|
70
|
+
edit: "tool.title.edit",
|
|
71
|
+
code: "tool.title.code",
|
|
72
|
+
others: "tool.title.generic"
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Known tool name -> variant.
|
|
76
|
+
*
|
|
77
|
+
* `cordis_define` is deliberately absent: ui-cordis registers a keyed
|
|
78
|
+
* `tool.call.toolview` entry for it, and a keyed hit REPLACES the generic row
|
|
79
|
+
* (this table is only reached through GenericToolCard, the dispatch fallback in
|
|
80
|
+
* ToolCallTree). An entry here would be unreachable, and a second title for the
|
|
81
|
+
* same call would be a second answer to a question the card already owns.
|
|
82
|
+
*/
|
|
83
|
+
const TOOL_VARIANTS = {
|
|
84
|
+
bash: "bash",
|
|
85
|
+
pwsh: "bash",
|
|
86
|
+
read: "read",
|
|
87
|
+
read_image: "read",
|
|
88
|
+
web_fetch: "read",
|
|
89
|
+
web_search: "search",
|
|
90
|
+
grep: "search",
|
|
91
|
+
glob: "search",
|
|
92
|
+
write: "write",
|
|
93
|
+
edit: "edit",
|
|
94
|
+
run_code: "code",
|
|
95
|
+
cordis_package_inspect: "read",
|
|
96
|
+
cordis_runtime_inspect: "read",
|
|
97
|
+
cordis_run: "others",
|
|
98
|
+
cordis_stop: "others",
|
|
99
|
+
cordis_undefine: "others"
|
|
100
|
+
};
|
|
101
|
+
/** Tool-owned titles that refine a generic row variant without replacing it. */
|
|
102
|
+
const TOOL_TITLE_KEYS = {
|
|
103
|
+
cordis_package_inspect: "tool.title.inspect",
|
|
104
|
+
cordis_runtime_inspect: "tool.title.inspect",
|
|
105
|
+
cordis_run: "tool.title.runCordis",
|
|
106
|
+
cordis_stop: "tool.title.stopCordis",
|
|
107
|
+
cordis_undefine: "tool.title.removeCordis",
|
|
108
|
+
pwsh: "tool.title.pwsh",
|
|
109
|
+
read_image: "tool.title.readImage"
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Classify a tool name into its row variant.
|
|
113
|
+
* @param toolName - wire tool name.
|
|
114
|
+
* @returns matching variant, others when unknown.
|
|
115
|
+
*/
|
|
116
|
+
function classifyTool(toolName) {
|
|
117
|
+
return TOOL_VARIANTS[toolName] ?? "others";
|
|
118
|
+
}
|
|
119
|
+
function deriveAutoReviewDenial(block) {
|
|
120
|
+
if (!("kind" in block) || !block.isError) return null;
|
|
121
|
+
const error = block.error;
|
|
122
|
+
if (error?.name !== "AutoReviewDeniedError" || error.code !== "AUTO_REVIEW_DENIED") return null;
|
|
123
|
+
return { reason: typeof error.reason === "string" ? error.reason : null };
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Flatten a settled result's content blocks to display text: text blocks
|
|
127
|
+
* verbatim, other block shapes as pretty JSON. Empty content on a failed call
|
|
128
|
+
* falls back to the structured error's `name: code` line.
|
|
129
|
+
* @param node - the settled result node.
|
|
130
|
+
* @returns the flattened result text (may be empty).
|
|
131
|
+
*/
|
|
132
|
+
function resultText(node) {
|
|
133
|
+
const parts = [];
|
|
134
|
+
for (const block of node.content) if (block.type === "text") parts.push(block.text);
|
|
135
|
+
else parts.push(JSON.stringify(block, null, 2));
|
|
136
|
+
if (parts.length === 0 && node.error !== void 0) parts.push(`${node.error.name}: ${node.error.code}`);
|
|
137
|
+
return parts.join("\n");
|
|
138
|
+
}
|
|
139
|
+
function parseArgs(argsRaw) {
|
|
140
|
+
try {
|
|
141
|
+
return JSON.parse(argsRaw);
|
|
142
|
+
} catch {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function firstLine(text) {
|
|
147
|
+
const nl = text.indexOf("\n");
|
|
148
|
+
return nl === -1 ? text : text.slice(0, nl);
|
|
149
|
+
}
|
|
150
|
+
function pickString(args, keys) {
|
|
151
|
+
for (const key of keys) {
|
|
152
|
+
const v = args[key];
|
|
153
|
+
if (typeof v === "string" && v !== "") return v;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/** Summary key preference per variant (args-derived; result-derived summaries are a ledger item). */
|
|
157
|
+
const SUMMARY_KEYS = {
|
|
158
|
+
bash: ["description", "command"],
|
|
159
|
+
read: [
|
|
160
|
+
"path",
|
|
161
|
+
"file_path",
|
|
162
|
+
"url"
|
|
163
|
+
],
|
|
164
|
+
search: [
|
|
165
|
+
"query",
|
|
166
|
+
"pattern",
|
|
167
|
+
"url"
|
|
168
|
+
],
|
|
169
|
+
write: ["path", "file_path"],
|
|
170
|
+
edit: ["path", "file_path"],
|
|
171
|
+
code: ["description"],
|
|
172
|
+
others: []
|
|
173
|
+
};
|
|
174
|
+
function deriveSummary(variant, argsRaw) {
|
|
175
|
+
const parsed = parseArgs(argsRaw);
|
|
176
|
+
if (typeof parsed !== "object" || parsed === null) return firstLine(argsRaw);
|
|
177
|
+
const args = parsed;
|
|
178
|
+
if (variant === "search" && Array.isArray(args.queries)) {
|
|
179
|
+
const queries = args.queries.filter((query) => typeof query === "string" && query !== "");
|
|
180
|
+
if (queries.length > 0) return queries.map(firstLine).join(", ");
|
|
181
|
+
}
|
|
182
|
+
const picked = pickString(args, SUMMARY_KEYS[variant]);
|
|
183
|
+
if (picked !== void 0) return firstLine(picked);
|
|
184
|
+
for (const v of Object.values(args)) if (typeof v === "string" && v !== "") return firstLine(v);
|
|
185
|
+
return firstLine(argsRaw);
|
|
186
|
+
}
|
|
187
|
+
/** Path keys only — never `url` (web_fetch lands on the read variant). */
|
|
188
|
+
const FILE_PATH_KEYS = ["path", "file_path"];
|
|
189
|
+
/** File-tool variants whose summary may be an openable workspace path. */
|
|
190
|
+
const FILE_PATH_VARIANTS = new Set([
|
|
191
|
+
"read",
|
|
192
|
+
"write",
|
|
193
|
+
"edit"
|
|
194
|
+
]);
|
|
195
|
+
function deriveFilePath(variant, argsRaw) {
|
|
196
|
+
if (!FILE_PATH_VARIANTS.has(variant)) return void 0;
|
|
197
|
+
const parsed = parseArgs(argsRaw);
|
|
198
|
+
if (typeof parsed !== "object" || parsed === null) return void 0;
|
|
199
|
+
const picked = pickString(parsed, FILE_PATH_KEYS);
|
|
200
|
+
return picked === void 0 ? void 0 : firstLine(picked);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Format one argument payload when its generic input body becomes visible.
|
|
204
|
+
* @param variant - row presentation selected for the Tool name.
|
|
205
|
+
* @param argsRaw - original argument JSON or incomplete raw text.
|
|
206
|
+
* @returns display body, or null for empty input.
|
|
207
|
+
*/
|
|
208
|
+
function formatToolBody(variant, argsRaw) {
|
|
209
|
+
if (argsRaw === "") return null;
|
|
210
|
+
const parsed = parseArgs(argsRaw);
|
|
211
|
+
if (parsed === void 0) return argsRaw;
|
|
212
|
+
if (variant === "code" && typeof parsed === "object" && parsed !== null) {
|
|
213
|
+
const code = parsed.code;
|
|
214
|
+
if (typeof code === "string" && code !== "") return code;
|
|
215
|
+
}
|
|
216
|
+
return JSON.stringify(parsed, null, 2);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Derive the full row model from a frozen call slice.
|
|
220
|
+
* @param toolName - wire tool name (dispatch-supplied; survives windowless results).
|
|
221
|
+
* @param block - RunningToolCall or ToolResultNode off the snapshot caches.
|
|
222
|
+
* @param cwd - session workspace root; workspace-rooted path summaries display relative to it.
|
|
223
|
+
* @param home - host account home; a leftover POSIX home path displays as `~`.
|
|
224
|
+
* @returns the row model.
|
|
225
|
+
*/
|
|
226
|
+
function toolRowModel(toolName, block, cwd, home) {
|
|
227
|
+
const variant = classifyTool(toolName);
|
|
228
|
+
const done = "kind" in block;
|
|
229
|
+
const argsRaw = (done ? block.call?.argsRaw : block.argsRaw) ?? "";
|
|
230
|
+
const state = !done ? "running" : block.error?.code === "interrupted" ? "stopped" : block.isError ? "error" : "ok";
|
|
231
|
+
const base = argsRaw === "" ? block.callId : abbreviateHomePath(relativizeToCwd(deriveSummary(variant, argsRaw), cwd), home);
|
|
232
|
+
const toolTitleKey = TOOL_TITLE_KEYS[toolName];
|
|
233
|
+
const summary = variant === "others" && toolName !== "" && toolTitleKey === void 0 ? `${toolName} · ${base}` : base;
|
|
234
|
+
const output = done ? resultText(block) || null : null;
|
|
235
|
+
const errorSummary = state === "error" && output !== null ? firstLine(output) : null;
|
|
236
|
+
const bodyRaw = argsRaw === "" ? null : argsRaw;
|
|
237
|
+
return {
|
|
238
|
+
variant,
|
|
239
|
+
titleKey: toolTitleKey ?? VARIANT_TITLE_KEYS[variant],
|
|
240
|
+
summary,
|
|
241
|
+
filePath: deriveFilePath(variant, argsRaw),
|
|
242
|
+
bodyRaw,
|
|
243
|
+
output,
|
|
244
|
+
errorSummary,
|
|
245
|
+
autoReviewDenial: deriveAutoReviewDenial(block),
|
|
246
|
+
state
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
//#endregion
|
|
63
250
|
//#region lib/types/client/tool/models/raw-tool-call.js
|
|
64
251
|
const parsedCalls = /* @__PURE__ */ new WeakMap();
|
|
65
252
|
/**
|
|
@@ -445,7 +632,7 @@ window.__ModuleLoader__.load({
|
|
|
445
632
|
}
|
|
446
633
|
/**
|
|
447
634
|
* Recognize a final spill-policy notice in persisted text, including notice-only output.
|
|
448
|
-
* This identifies the text convention, not authenticated
|
|
635
|
+
* This identifies the text convention, not authenticated tool-output origin.
|
|
449
636
|
* @param text - complete recorded text result.
|
|
450
637
|
* @returns whether a complete notice occupies the end of the result.
|
|
451
638
|
*/
|
|
@@ -475,6 +662,7 @@ window.__ModuleLoader__.load({
|
|
|
475
662
|
return {
|
|
476
663
|
signal: (signal) => t("terminal.signal", { signal }),
|
|
477
664
|
exitCode: (code) => t("terminal.exitCode", { code }),
|
|
665
|
+
noExitCode: t("terminal.noExitCode"),
|
|
478
666
|
running: t("terminal.running"),
|
|
479
667
|
failed: t("terminal.failed"),
|
|
480
668
|
done: t("terminal.done"),
|
|
@@ -677,7 +865,7 @@ window.__ModuleLoader__.load({
|
|
|
677
865
|
}
|
|
678
866
|
/**
|
|
679
867
|
* Derive terminal props for supported shell and terminal-send calls, including
|
|
680
|
-
* nested
|
|
868
|
+
* nested PTC dispatch calls. Standard shell results parse their final status
|
|
681
869
|
* marker; persistent shell results, spill previews, background calls, errors,
|
|
682
870
|
* and malformed input use the generic path. {@link isSettledPersistentShellCall} lets that generic
|
|
683
871
|
* persistent result remain expandable without inventing one process status.
|
|
@@ -791,183 +979,28 @@ window.__ModuleLoader__.load({
|
|
|
791
979
|
};
|
|
792
980
|
}
|
|
793
981
|
//#endregion
|
|
794
|
-
//#region lib/types/client/tool/models/
|
|
795
|
-
/** Locale key per generic row variant. */
|
|
796
|
-
const VARIANT_TITLE_KEYS = {
|
|
797
|
-
search: "tool.title.search",
|
|
798
|
-
read: "tool.title.read",
|
|
799
|
-
bash: "tool.title.bash",
|
|
800
|
-
write: "tool.title.write",
|
|
801
|
-
edit: "tool.title.edit",
|
|
802
|
-
code: "tool.title.code",
|
|
803
|
-
others: "tool.title.generic"
|
|
804
|
-
};
|
|
805
|
-
/**
|
|
806
|
-
* Known tool name -> variant.
|
|
807
|
-
*
|
|
808
|
-
* `cordis_define` is deliberately absent: ui-cordis registers a keyed
|
|
809
|
-
* `tool.call.toolview` entry for it, and a keyed hit REPLACES the generic row
|
|
810
|
-
* (this table is only reached through GenericToolCard, the dispatch fallback in
|
|
811
|
-
* ToolCallTree). An entry here would be unreachable, and a second title for the
|
|
812
|
-
* same call would be a second answer to a question the card already owns.
|
|
813
|
-
*/
|
|
814
|
-
const TOOL_VARIANTS = {
|
|
815
|
-
bash: "bash",
|
|
816
|
-
pwsh: "bash",
|
|
817
|
-
read: "read",
|
|
818
|
-
read_image: "read",
|
|
819
|
-
web_fetch: "read",
|
|
820
|
-
web_search: "search",
|
|
821
|
-
grep: "search",
|
|
822
|
-
glob: "search",
|
|
823
|
-
write: "write",
|
|
824
|
-
edit: "edit",
|
|
825
|
-
run_code: "code",
|
|
826
|
-
cordis_package_inspect: "read",
|
|
827
|
-
cordis_runtime_inspect: "read",
|
|
828
|
-
cordis_run: "others",
|
|
829
|
-
cordis_stop: "others",
|
|
830
|
-
cordis_undefine: "others"
|
|
831
|
-
};
|
|
832
|
-
/** Tool-owned titles that refine a generic row variant without replacing it. */
|
|
833
|
-
const TOOL_TITLE_KEYS = {
|
|
834
|
-
cordis_package_inspect: "tool.title.inspect",
|
|
835
|
-
cordis_runtime_inspect: "tool.title.inspect",
|
|
836
|
-
cordis_run: "tool.title.runCordis",
|
|
837
|
-
cordis_stop: "tool.title.stopCordis",
|
|
838
|
-
cordis_undefine: "tool.title.removeCordis",
|
|
839
|
-
pwsh: "tool.title.pwsh",
|
|
840
|
-
read_image: "tool.title.readImage"
|
|
841
|
-
};
|
|
842
|
-
/**
|
|
843
|
-
* Classify a tool name into its row variant.
|
|
844
|
-
* @param toolName - wire tool name.
|
|
845
|
-
* @returns matching variant, others when unknown.
|
|
846
|
-
*/
|
|
847
|
-
function classifyTool(toolName) {
|
|
848
|
-
return TOOL_VARIANTS[toolName] ?? "others";
|
|
849
|
-
}
|
|
850
|
-
/**
|
|
851
|
-
* Flatten a settled result's content blocks to display text: text blocks
|
|
852
|
-
* verbatim, other block shapes as pretty JSON. Empty content on a failed call
|
|
853
|
-
* falls back to the structured error's `name: code` line.
|
|
854
|
-
* @param node - the settled result node.
|
|
855
|
-
* @returns the flattened result text (may be empty).
|
|
856
|
-
*/
|
|
857
|
-
function resultText(node) {
|
|
858
|
-
const parts = [];
|
|
859
|
-
for (const block of node.content) if (block.type === "text") parts.push(block.text);
|
|
860
|
-
else parts.push(JSON.stringify(block, null, 2));
|
|
861
|
-
if (parts.length === 0 && node.error !== void 0) parts.push(`${node.error.name}: ${node.error.code}`);
|
|
862
|
-
return parts.join("\n");
|
|
863
|
-
}
|
|
864
|
-
function parseArgs(argsRaw) {
|
|
865
|
-
try {
|
|
866
|
-
return JSON.parse(argsRaw);
|
|
867
|
-
} catch {
|
|
868
|
-
return;
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
function firstLine(text) {
|
|
872
|
-
const nl = text.indexOf("\n");
|
|
873
|
-
return nl === -1 ? text : text.slice(0, nl);
|
|
874
|
-
}
|
|
875
|
-
function pickString(args, keys) {
|
|
876
|
-
for (const key of keys) {
|
|
877
|
-
const v = args[key];
|
|
878
|
-
if (typeof v === "string" && v !== "") return v;
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
/** Summary key preference per variant (args-derived; result-derived summaries are a ledger item). */
|
|
882
|
-
const SUMMARY_KEYS = {
|
|
883
|
-
bash: ["description", "command"],
|
|
884
|
-
read: [
|
|
885
|
-
"path",
|
|
886
|
-
"file_path",
|
|
887
|
-
"url"
|
|
888
|
-
],
|
|
889
|
-
search: [
|
|
890
|
-
"query",
|
|
891
|
-
"pattern",
|
|
892
|
-
"url"
|
|
893
|
-
],
|
|
894
|
-
write: ["path", "file_path"],
|
|
895
|
-
edit: ["path", "file_path"],
|
|
896
|
-
code: ["description"],
|
|
897
|
-
others: []
|
|
898
|
-
};
|
|
899
|
-
function deriveSummary(variant, argsRaw) {
|
|
900
|
-
const parsed = parseArgs(argsRaw);
|
|
901
|
-
if (typeof parsed !== "object" || parsed === null) return firstLine(argsRaw);
|
|
902
|
-
const args = parsed;
|
|
903
|
-
if (variant === "search" && Array.isArray(args.queries)) {
|
|
904
|
-
const queries = args.queries.filter((query) => typeof query === "string" && query !== "");
|
|
905
|
-
if (queries.length > 0) return queries.map(firstLine).join(", ");
|
|
906
|
-
}
|
|
907
|
-
const picked = pickString(args, SUMMARY_KEYS[variant]);
|
|
908
|
-
if (picked !== void 0) return firstLine(picked);
|
|
909
|
-
for (const v of Object.values(args)) if (typeof v === "string" && v !== "") return firstLine(v);
|
|
910
|
-
return firstLine(argsRaw);
|
|
911
|
-
}
|
|
912
|
-
/** Path keys only — never `url` (web_fetch lands on the read variant). */
|
|
913
|
-
const FILE_PATH_KEYS = ["path", "file_path"];
|
|
914
|
-
/** File-tool variants whose summary may be an openable workspace path. */
|
|
915
|
-
const FILE_PATH_VARIANTS = new Set([
|
|
916
|
-
"read",
|
|
917
|
-
"write",
|
|
918
|
-
"edit"
|
|
919
|
-
]);
|
|
920
|
-
function deriveFilePath(variant, argsRaw) {
|
|
921
|
-
if (!FILE_PATH_VARIANTS.has(variant)) return void 0;
|
|
922
|
-
const parsed = parseArgs(argsRaw);
|
|
923
|
-
if (typeof parsed !== "object" || parsed === null) return void 0;
|
|
924
|
-
const picked = pickString(parsed, FILE_PATH_KEYS);
|
|
925
|
-
return picked === void 0 ? void 0 : firstLine(picked);
|
|
926
|
-
}
|
|
982
|
+
//#region lib/types/client/tool/models/auto-review-denial.js
|
|
927
983
|
/**
|
|
928
|
-
*
|
|
929
|
-
* @param
|
|
930
|
-
* @
|
|
931
|
-
* @returns display body, or null for empty input.
|
|
984
|
+
* Normalize only the user-visible copy; the durable error keeps the raw reason.
|
|
985
|
+
* @param reason - raw persisted reviewer reason, or null when none was recorded.
|
|
986
|
+
* @returns one display line, or null when the reason has no displayable text.
|
|
932
987
|
*/
|
|
933
|
-
function
|
|
934
|
-
if (
|
|
935
|
-
const
|
|
936
|
-
|
|
937
|
-
if (variant === "code" && typeof parsed === "object" && parsed !== null) {
|
|
938
|
-
const code = parsed.code;
|
|
939
|
-
if (typeof code === "string" && code !== "") return code;
|
|
940
|
-
}
|
|
941
|
-
return JSON.stringify(parsed, null, 2);
|
|
988
|
+
function normalizeAutoReviewReason(reason) {
|
|
989
|
+
if (reason === null) return null;
|
|
990
|
+
const normalized = reason.trim().replace(/[\r\n\u2028\u2029]+/gu, " ");
|
|
991
|
+
return normalized === "" ? null : normalized;
|
|
942
992
|
}
|
|
943
993
|
/**
|
|
944
|
-
*
|
|
945
|
-
* @param
|
|
946
|
-
* @param
|
|
947
|
-
* @
|
|
948
|
-
* @param home - host account home; a leftover POSIX home path displays as `~`.
|
|
949
|
-
* @returns the row model.
|
|
994
|
+
* Resolve the collapsed identity and the single expanded OUT line.
|
|
995
|
+
* @param denial - locale-neutral persisted denial facts.
|
|
996
|
+
* @param t - conversation-namespace translator.
|
|
997
|
+
* @returns localized summary and output text for the Tool row.
|
|
950
998
|
*/
|
|
951
|
-
function
|
|
952
|
-
const
|
|
953
|
-
const done = "kind" in block;
|
|
954
|
-
const argsRaw = (done ? block.call?.argsRaw : block.argsRaw) ?? "";
|
|
955
|
-
const state = !done ? "running" : block.error?.code === "interrupted" ? "stopped" : block.isError ? "error" : "ok";
|
|
956
|
-
const base = argsRaw === "" ? block.callId : abbreviateHomePath(relativizeToCwd(deriveSummary(variant, argsRaw), cwd), home);
|
|
957
|
-
const toolTitleKey = TOOL_TITLE_KEYS[toolName];
|
|
958
|
-
const summary = variant === "others" && toolName !== "" && toolTitleKey === void 0 ? `${toolName} · ${base}` : base;
|
|
959
|
-
const output = done ? resultText(block) || null : null;
|
|
960
|
-
const errorSummary = state === "error" && output !== null ? firstLine(output) : null;
|
|
961
|
-
const bodyRaw = argsRaw === "" ? null : argsRaw;
|
|
999
|
+
function localizeAutoReviewDenial(denial, t) {
|
|
1000
|
+
const reason = normalizeAutoReviewReason(denial.reason) ?? t("tool.autoReviewReasonFallback");
|
|
962
1001
|
return {
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
summary,
|
|
966
|
-
filePath: deriveFilePath(variant, argsRaw),
|
|
967
|
-
bodyRaw,
|
|
968
|
-
output,
|
|
969
|
-
errorSummary,
|
|
970
|
-
state
|
|
1002
|
+
summary: t("tool.autoReviewRejected"),
|
|
1003
|
+
output: t("tool.autoReviewNotExecuted", { reason })
|
|
971
1004
|
};
|
|
972
1005
|
}
|
|
973
1006
|
//#endregion
|
|
@@ -1218,13 +1251,14 @@ window.__ModuleLoader__.load({
|
|
|
1218
1251
|
const searchBody = search ?? null;
|
|
1219
1252
|
const webBody = web ?? null;
|
|
1220
1253
|
const askQuestionBody = askQuestion ?? null;
|
|
1254
|
+
const inputRaw = bodyRaw ?? null;
|
|
1221
1255
|
const outputText = output ?? null;
|
|
1222
1256
|
const card = askQuestionBody ?? terminalBody ?? diffBody ?? readBody ?? imageBody ?? searchBody ?? webBody;
|
|
1223
|
-
const expandable =
|
|
1257
|
+
const expandable = inputRaw !== null || outputText !== null || card !== null;
|
|
1224
1258
|
const open = expanded && expandable;
|
|
1225
|
-
const bodyText = (0, react.useMemo)(() => open && card === null &&
|
|
1226
|
-
bodyRaw,
|
|
1259
|
+
const bodyText = (0, react.useMemo)(() => open && card === null && inputRaw !== null ? formatToolBody(variant, inputRaw) : null, [
|
|
1227
1260
|
card,
|
|
1261
|
+
inputRaw,
|
|
1228
1262
|
open,
|
|
1229
1263
|
variant
|
|
1230
1264
|
]);
|
|
@@ -1237,16 +1271,14 @@ window.__ModuleLoader__.load({
|
|
|
1237
1271
|
return `+${added} -${removed}`;
|
|
1238
1272
|
}, [diffBody]);
|
|
1239
1273
|
const suffix = failureLine === null ? summarySuffix ?? diffStat : null;
|
|
1240
|
-
const fileLink = filePath !== void 0 && onOpenFile !== void 0 && failureLine === null;
|
|
1241
1274
|
const toggleExpand = () => {
|
|
1242
1275
|
setExpanded((v) => !v);
|
|
1243
1276
|
};
|
|
1244
|
-
const openFile = (event) => {
|
|
1277
|
+
const openFile = filePath !== void 0 && onOpenFile !== void 0 && failureLine === null ? (event) => {
|
|
1245
1278
|
event.stopPropagation();
|
|
1246
|
-
if (filePath === void 0 || onOpenFile === void 0) return;
|
|
1247
1279
|
if (filePathLine === void 0) onOpenFile(filePath);
|
|
1248
1280
|
else onOpenFile(filePath, { line: filePathLine });
|
|
1249
|
-
};
|
|
1281
|
+
} : void 0;
|
|
1250
1282
|
const fileLinkKeyDown = (event) => {
|
|
1251
1283
|
if (event.key === "Enter" || event.key === " ") event.stopPropagation();
|
|
1252
1284
|
};
|
|
@@ -1276,7 +1308,7 @@ window.__ModuleLoader__.load({
|
|
|
1276
1308
|
className: ToolRow_module_css_default.sep,
|
|
1277
1309
|
"aria-hidden": true
|
|
1278
1310
|
}),
|
|
1279
|
-
|
|
1311
|
+
openFile !== void 0 ? (0, react_jsx_runtime.jsx)("button", {
|
|
1280
1312
|
type: "button",
|
|
1281
1313
|
className: ToolRow_module_css_default.fileLink,
|
|
1282
1314
|
onClick: openFile,
|
|
@@ -1301,7 +1333,7 @@ window.__ModuleLoader__.load({
|
|
|
1301
1333
|
}) : diffBody !== null ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.DiffBlock, {
|
|
1302
1334
|
...diffBody.card,
|
|
1303
1335
|
labels: diffLabels,
|
|
1304
|
-
maxLines:
|
|
1336
|
+
maxLines: 9,
|
|
1305
1337
|
className: ToolRow_module_css_default.diffBody
|
|
1306
1338
|
}) : readBody !== null ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.ReadBlock, {
|
|
1307
1339
|
...readBody,
|
|
@@ -1399,6 +1431,7 @@ window.__ModuleLoader__.load({
|
|
|
1399
1431
|
};
|
|
1400
1432
|
function GenericToolCard({ toolName, block, cwd, home, openFile, inspect, t }) {
|
|
1401
1433
|
const model = toolRowModel(toolName, block, cwd, home);
|
|
1434
|
+
const autoReview = model.autoReviewDenial === null ? null : localizeAutoReviewDenial(model.autoReviewDenial, t);
|
|
1402
1435
|
const terminal = terminalCardModel(block, cwd);
|
|
1403
1436
|
const read = readCardModel(block, cwd, home);
|
|
1404
1437
|
const diff = diffCardModel(block);
|
|
@@ -1413,9 +1446,9 @@ window.__ModuleLoader__.load({
|
|
|
1413
1446
|
icon: VARIANT_ICONS[model.variant],
|
|
1414
1447
|
title: t(model.titleKey),
|
|
1415
1448
|
summary: model.summary,
|
|
1416
|
-
bodyRaw: singleFile ? null : model.bodyRaw,
|
|
1417
|
-
output: model.output,
|
|
1418
|
-
errorSummary: model.errorSummary,
|
|
1449
|
+
bodyRaw: singleFile || autoReview !== null ? null : model.bodyRaw,
|
|
1450
|
+
output: autoReview?.output ?? model.output,
|
|
1451
|
+
errorSummary: autoReview?.summary ?? model.errorSummary,
|
|
1419
1452
|
terminal,
|
|
1420
1453
|
diff,
|
|
1421
1454
|
read,
|
|
@@ -1472,11 +1505,15 @@ window.__ModuleLoader__.load({
|
|
|
1472
1505
|
loadImage,
|
|
1473
1506
|
inspectCall
|
|
1474
1507
|
]);
|
|
1508
|
+
const autoReviewDenied = (0, react.useMemo)(() => toolRowModel(toolName, block).autoReviewDenial !== null, [toolName, block]);
|
|
1475
1509
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
1476
1510
|
className: ToolCallTree_module_css_default.callRow,
|
|
1477
1511
|
"data-chat-anchor-key": `call:${callId}`,
|
|
1478
1512
|
"data-chat-call-id": callId,
|
|
1479
|
-
children: [
|
|
1513
|
+
children: [autoReviewDenied ? (0, react_jsx_runtime.jsx)(GenericToolCard, {
|
|
1514
|
+
...owner,
|
|
1515
|
+
t
|
|
1516
|
+
}) : renderSlot("tool.call.toolview", owner, {
|
|
1480
1517
|
entryKey: toolName,
|
|
1481
1518
|
fallback: (0, react_jsx_runtime.jsx)(GenericToolCard, {
|
|
1482
1519
|
...owner,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import type { AutoReviewDenial } from './tool-call-model.ts';
|
|
3
|
+
/** Localized copy that replaces ordinary failed-call output for an Auto denial. */
|
|
4
|
+
export interface AutoReviewDenialPresentation {
|
|
5
|
+
summary: string;
|
|
6
|
+
output: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Normalize only the user-visible copy; the durable error keeps the raw reason.
|
|
10
|
+
* @param reason - raw persisted reviewer reason, or null when none was recorded.
|
|
11
|
+
* @returns one display line, or null when the reason has no displayable text.
|
|
12
|
+
*/
|
|
13
|
+
export declare function normalizeAutoReviewReason(reason: string | null): string | null;
|
|
14
|
+
/**
|
|
15
|
+
* Resolve the collapsed identity and the single expanded OUT line.
|
|
16
|
+
* @param denial - locale-neutral persisted denial facts.
|
|
17
|
+
* @param t - conversation-namespace translator.
|
|
18
|
+
* @returns localized summary and output text for the Tool row.
|
|
19
|
+
*/
|
|
20
|
+
export declare function localizeAutoReviewDenial(denial: AutoReviewDenial, t: TranslateNS<'conversation'>): AutoReviewDenialPresentation;
|
|
21
|
+
//# sourceMappingURL=auto-review-denial.d.ts.map
|
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
/** Pure diff-card derivation from raw file-mutation calls and result metadata. @module */
|
|
2
2
|
import type { DiffBlockProps } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
3
3
|
import type { ToolCallBlock } from './tool-call-model.ts';
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
-
* primitive's own default, which the details panel keeps. A chat row is a
|
|
7
|
-
* summary surface inside the message flow: the flow must stay scannable across
|
|
8
|
-
* many calls, while the details panel is the single-call reading surface. The
|
|
9
|
-
* same split {@link CHAT_TERMINAL_MAX_LINES} draws for a terminal card, so the
|
|
10
|
-
* two card kinds cap a long body at the same place in the flow. A design
|
|
11
|
-
* constant of this UI's row geometry, not a deployment choice.
|
|
12
|
-
*/
|
|
13
|
-
export declare const CHAT_DIFF_MAX_LINES = 8;
|
|
4
|
+
/** Room for a path, one removed/added pair, and three context lines on each side. */
|
|
5
|
+
export declare const CHAT_DIFF_MAX_LINES = 9;
|
|
14
6
|
/**
|
|
15
7
|
* The {@link DiffBlock} props this derivation owns. Picked off the primitive's
|
|
16
8
|
* props so the two stay in step; `maxLines`/`className` belong to each render
|
|
@@ -74,7 +74,7 @@ export declare function isSettledPersistentShellCall(block: ToolCallBlock): bool
|
|
|
74
74
|
export declare function isSpilledShellCall(block: ToolCallBlock): boolean;
|
|
75
75
|
/**
|
|
76
76
|
* Derive terminal props for supported shell and terminal-send calls, including
|
|
77
|
-
* nested
|
|
77
|
+
* nested PTC dispatch calls. Standard shell results parse their final status
|
|
78
78
|
* marker; persistent shell results, spill previews, background calls, errors,
|
|
79
79
|
* and malformed input use the generic path. {@link isSettledPersistentShellCall} lets that generic
|
|
80
80
|
* persistent result remain expandable without inventing one process status.
|
|
@@ -12,6 +12,11 @@ export type { ToolCallBlock } from '@deepseek-ai/dsh-client-ui-chat/client';
|
|
|
12
12
|
export type ToolRowVariant = 'search' | 'read' | 'bash' | 'write' | 'edit' | 'code' | 'others';
|
|
13
13
|
/** Row state semantic; colors self-supplied via StateDot (design gives none). */
|
|
14
14
|
export type ToolRowState = 'running' | 'ok' | 'error' | 'stopped';
|
|
15
|
+
/** Locale-neutral structured fact consumed only by the user-facing Tool row. */
|
|
16
|
+
export interface AutoReviewDenial {
|
|
17
|
+
/** Raw persisted reviewer reason; display normalization happens at render time. */
|
|
18
|
+
reason: string | null;
|
|
19
|
+
}
|
|
15
20
|
type ToolTitleKey = Extract<LocaleKeysOf<'conversation'>, `tool.title.${string}`>;
|
|
16
21
|
/** Locale key per generic row variant. */
|
|
17
22
|
export declare const VARIANT_TITLE_KEYS: {
|
|
@@ -46,6 +51,8 @@ export interface ToolRowModel {
|
|
|
46
51
|
output: string | null;
|
|
47
52
|
/** First line of the result text on an error row; null for every other state. */
|
|
48
53
|
errorSummary: string | null;
|
|
54
|
+
/** Structured Auto-review denial identity; null for every ordinary result. */
|
|
55
|
+
autoReviewDenial: AutoReviewDenial | null;
|
|
49
56
|
state: ToolRowState;
|
|
50
57
|
}
|
|
51
58
|
/**
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-ui-tool",
|
|
3
3
|
"description": "Client Tool call-tree renderer and keyed per-tool presentation slot",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.6-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -46,28 +46,28 @@
|
|
|
46
46
|
"react": "^18.2.0",
|
|
47
47
|
"react-dom": "^18.2.0",
|
|
48
48
|
"clsx": "^2.0.0",
|
|
49
|
-
"@deepseek-ai/dsh-
|
|
50
|
-
"@deepseek-ai/dsh-
|
|
51
|
-
"@deepseek-ai/dsh-
|
|
52
|
-
"@deepseek-ai/dsh-
|
|
53
|
-
"@deepseek-ai/dsh-
|
|
54
|
-
"@deepseek-ai/dsh-tools": "^0.1.
|
|
55
|
-
"@deepseek-ai/dsh-
|
|
49
|
+
"@deepseek-ai/dsh-spill-policy": "^0.1.6-alpha.2",
|
|
50
|
+
"@deepseek-ai/dsh-agent": "^0.1.6-alpha.2",
|
|
51
|
+
"@deepseek-ai/dsh-llm": "^0.1.6-alpha.2",
|
|
52
|
+
"@deepseek-ai/dsh-session": "^0.1.6-alpha.2",
|
|
53
|
+
"@deepseek-ai/dsh-system-prompt": "^0.1.6-alpha.2",
|
|
54
|
+
"@deepseek-ai/dsh-tools": "^0.1.6-alpha.2",
|
|
55
|
+
"@deepseek-ai/dsh-spill": "^0.1.6-alpha.2",
|
|
56
56
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
57
|
-
"@deepseek-ai/dsh-
|
|
58
|
-
"@deepseek-ai/dsh-
|
|
59
|
-
"@deepseek-ai/dsh-client-locale": "^0.1.
|
|
60
|
-
"@deepseek-ai/dsh-client-
|
|
61
|
-
"@deepseek-ai/dsh-client-
|
|
62
|
-
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.
|
|
63
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.1.
|
|
64
|
-
"@deepseek-ai/dsh-
|
|
65
|
-
"@deepseek-ai/dsh-client-ui-
|
|
66
|
-
"@deepseek-ai/dsh-client-ui-session": "^0.1.
|
|
67
|
-
"@deepseek-ai/dsh-util-workspace-path": "^0.1.
|
|
68
|
-
"@deepseek-ai/dsh-attachment": "^0.1.
|
|
69
|
-
"@deepseek-ai/dsh-
|
|
70
|
-
"@deepseek-ai/dsh-
|
|
57
|
+
"@deepseek-ai/dsh-api-remotes": "^0.1.6-alpha.2",
|
|
58
|
+
"@deepseek-ai/dsh-client-connection": "^0.1.6-alpha.2",
|
|
59
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.6-alpha.2",
|
|
60
|
+
"@deepseek-ai/dsh-client-test-runtime": "^0.1.6-alpha.2",
|
|
61
|
+
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.6-alpha.2",
|
|
62
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.6-alpha.2",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.6-alpha.2",
|
|
64
|
+
"@deepseek-ai/dsh-api-workspace-controller": "^0.1.6-alpha.2",
|
|
65
|
+
"@deepseek-ai/dsh-client-ui-chat": "^0.1.6-alpha.2",
|
|
66
|
+
"@deepseek-ai/dsh-client-ui-session": "^0.1.6-alpha.2",
|
|
67
|
+
"@deepseek-ai/dsh-util-workspace-path": "^0.1.6-alpha.2",
|
|
68
|
+
"@deepseek-ai/dsh-attachment": "^0.1.6-alpha.2",
|
|
69
|
+
"@deepseek-ai/dsh-ptc-runtime": "^0.1.6-alpha.2",
|
|
70
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.6-alpha.2"
|
|
71
71
|
},
|
|
72
72
|
"files": [
|
|
73
73
|
"lib/index.js",
|