@deepseek-ai/dsh-client-ui-user-questions 0.1.6-alpha.1 → 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 +6 -4
- package/README.zh.md +6 -4
- package/lib/client.js +69 -66
- package/lib/types/client/PlanReviewPanel.d.ts +3 -3
- package/lib/types/client/contract/slots.d.ts +22 -12
- package/package.json +18 -17
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-user-questions/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: abbf855706b478857540b12712c5999082b0ab22
|
|
6
|
+
README.zh.md: 995035cbb08ff6c64e2b91b61ab49b2bd473b9b7
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
|
|
|
9
9
|
|
|
10
10
|
## Summary
|
|
11
11
|
|
|
12
|
-
When an agent asks a question in the Web client, this package replaces the chat composer with an interactive question surface. Users can move through questions, choose one or multiple options, enter custom answers, skip items, and submit one structured answer batch. Single-choice selections advance immediately, while drafts survive Session navigation for the lifetime of the page. A single question with a supported presentation intent can use a dedicated surface, including the plan-review card with `
|
|
12
|
+
When an agent asks a question in the Web client, this package replaces the chat composer with an interactive question surface. Users can move through questions, choose one or multiple options, enter custom answers, skip items, and submit one structured answer batch. Single-choice selections advance immediately, while drafts survive Session navigation for the lifetime of the page. A single question with a supported presentation intent can use a dedicated surface, including the plan-review card with `Request changes` and `Approve` actions.
|
|
13
13
|
|
|
14
14
|
## Table of Contents
|
|
15
15
|
|
|
@@ -33,11 +33,11 @@ A multi-select draft keeps its selected labels while the user opens or edits the
|
|
|
33
33
|
|
|
34
34
|
### The plan-review card
|
|
35
35
|
|
|
36
|
-
A `plan-review` intent — set by `dsh-plan-mode` on the `exit_plan_mode` review — renders
|
|
36
|
+
A `plan-review` intent — set by `dsh-plan-mode` on the `exit_plan_mode` review — renders a compact approval card: a `Plan review` strip with a `View full plan` link, the plan title and a two-line plain-text summary, and `Request changes` / `Approve` actions. The complete plan opens in the sidebar through the link or its permanent Chat card. Approve answers with the asker's approval label; `Request changes` rejects the wait as `ASK_CANCELLED`, returning the composer for the user's feedback without submitting an approval. The card has no separate refusal button.
|
|
37
37
|
|
|
38
38
|
### Failure and recovery
|
|
39
39
|
|
|
40
|
-
The generic question flow keeps its current page, selected labels, custom text, and explicit skips in a non-persisted Slot store scoped to the owning Session and keyed by the pending request's local render identity. Switching from Session A to B
|
|
40
|
+
The generic question flow keeps its current page, selected labels, custom text, and explicit skips in a non-persisted Slot store scoped to the owning Session generation and keyed by the pending request's local render identity. Switching from Session A to B retires A when no other reference owns it, so returning to A starts an empty question draft; another reference that keeps A's generation alive also keeps that draft. A different request identity reads an empty draft and replaces the previous value on its first edit; a successful answer or cancellation clears the matching value. The host remains authoritative for whether the request is pending.
|
|
41
41
|
|
|
42
42
|
-----
|
|
43
43
|
|
|
@@ -51,12 +51,14 @@ The package is one ownership rule: rendering a question is a host UI capability,
|
|
|
51
51
|
|
|
52
52
|
### Intent surface election
|
|
53
53
|
|
|
54
|
-
The card
|
|
54
|
+
The card accepts one question declaring the intent, carrying the plan as `detail`, and offering the named approve label, with at most one alternative and no multi-select. Its secondary action returns to the composer for change requests. Larger choices and multi-select questions remain in the generic flow.
|
|
55
55
|
|
|
56
56
|
### Copy and locale
|
|
57
57
|
|
|
58
58
|
Composer chrome copy (pager, buttons, placeholders, validation feedback) is bilingual: the plugin registers zh/en dictionaries under the `question` namespace of `dsh-client-locale` and hands the entry its bound translator plus the locale snapshot source through the inject face, so a locale switch re-renders a mounted composer. Question and option text arrives from the model and renders verbatim; carrier failure messages also display untranslated.
|
|
59
59
|
|
|
60
|
+
A plan review exposes `conversation.plan-review.actions` with its request key, full text, and optional invocation identity. The plan plugin opens logged plans from history and unlogged reviews as temporary sidebar previews. Opening a document does not answer or dismiss the review.
|
|
61
|
+
|
|
60
62
|
</details>
|
|
61
63
|
|
|
62
64
|
-----
|
package/README.zh.md
CHANGED
|
@@ -9,7 +9,7 @@ kind: "package-reference"
|
|
|
9
9
|
|
|
10
10
|
## 概述
|
|
11
11
|
|
|
12
|
-
当 agent(智能体)在 Web 客户端中提问时,本包会用交互式提问界面接管聊天编辑器。用户可以在问题之间导航、选择一个或多个选项、输入自定义答案、跳过问题,并提交一批结构化答案。选择单选项后会立即前进,而草稿会在当前页面的生命周期内跨会话导航保留。若唯一的问题声明了受支持的呈现意图,则可使用专用界面,包括带 `
|
|
12
|
+
当 agent(智能体)在 Web 客户端中提问时,本包会用交互式提问界面接管聊天编辑器。用户可以在问题之间导航、选择一个或多个选项、输入自定义答案、跳过问题,并提交一批结构化答案。选择单选项后会立即前进,而草稿会在当前页面的生命周期内跨会话导航保留。若唯一的问题声明了受支持的呈现意图,则可使用专用界面,包括带 `Request changes` 和 `Approve` 操作的 plan-review 卡片。
|
|
13
13
|
|
|
14
14
|
## 目录
|
|
15
15
|
|
|
@@ -33,11 +33,11 @@ kind: "package-reference"
|
|
|
33
33
|
|
|
34
34
|
### plan-review 卡片
|
|
35
35
|
|
|
36
|
-
`plan-review` 意图——由 `dsh-plan-mode` 在 `exit_plan_mode`
|
|
36
|
+
`plan-review` 意图——由 `dsh-plan-mode` 在 `exit_plan_mode` 审阅上设置——渲染紧凑审批卡片:顶部为带“查看全文”链接的“计划待审”条带,正文显示计划标题和两行纯文本摘要,底部提供“要求修改”和“同意执行”。通过链接或聊天历史中的常驻卡片可在侧边栏阅读完整计划。“同意执行”用提问方的批准标签回答;“要求修改”以 `ASK_CANCELLED` 拒绝等待,让编辑器归位供用户输入反馈,不会提交批准。卡片不再单列拒绝按钮。
|
|
37
37
|
|
|
38
38
|
### 失败与恢复
|
|
39
39
|
|
|
40
|
-
通用提问流程把当前题号、已选标签、自定义文本和显式跳过状态保存在非持久化 slot
|
|
40
|
+
通用提问流程把当前题号、已选标签、自定义文本和显式跳过状态保存在非持久化 slot 存储中;该存储归属对应 Session generation,并以待处理请求的本地渲染标识为键。从 Session A 切换到 B 时,如果没有其他引用持有 A,A 就会结束,因此返回 A 时会得到空的问题草稿;如果另一个引用继续持有 A 的 generation,该草稿也会保留。不同的请求标识读取空草稿,并在首次编辑时替换旧值;成功回答或取消会清除相符的值。请求是否仍在等待由主机保持权威。
|
|
41
41
|
|
|
42
42
|
-----
|
|
43
43
|
|
|
@@ -51,12 +51,14 @@ kind: "package-reference"
|
|
|
51
51
|
|
|
52
52
|
### 意图界面选择
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
卡片接管声明了意图、以 `detail` 携带计划、提供了被指名的批准标签的单个问题,要求除批准外最多一个选项,且非多选。次要操作返回编辑器供用户提出修改要求。更多选项或多选问题仍由通用流程处理。
|
|
55
55
|
|
|
56
56
|
### 文案与 locale
|
|
57
57
|
|
|
58
58
|
编辑器外框文案(翻页器、按钮、占位符、校验提示)是双语的:插件在 `dsh-client-locale` 的 `question` 命名空间下注册 zh/en 词典,并通过 inject face 把绑定的翻译函数和 locale 快照源交给该条目,因此切换语言会重新渲染已挂载的编辑器。问题与选项文本来自模型并原样渲染;载体失败消息也不经翻译直接显示。
|
|
59
59
|
|
|
60
|
+
计划审批通过 `conversation.plan-review.actions` 插槽提供请求键、完整正文和可选的调用标识。计划插件从历史中打开已记录计划,并把没有调用标识的审批作为临时侧边栏预览打开。打开文档不会回答或关闭审批。
|
|
61
|
+
|
|
60
62
|
</details>
|
|
61
63
|
|
|
62
64
|
-----
|
package/lib/client.js
CHANGED
|
@@ -21,16 +21,10 @@ window.__ModuleLoader__.load({
|
|
|
21
21
|
* Narrow a request to a renderable plan review, or return undefined to leave it
|
|
22
22
|
* to the generic question flow.
|
|
23
23
|
*
|
|
24
|
-
* The card
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* label the intent names, and is a binary single choice: at most one option
|
|
29
|
-
* besides approve, and not multi-select. A third option or a multi-select batch
|
|
30
|
-
* has answers two buttons cannot express, so the generic flow keeps it — as it
|
|
31
|
-
* keeps any request whose intent the asker's own service would have rejected,
|
|
32
|
-
* because the client sits downstream of a wire boundary and every request must
|
|
33
|
-
* stay answerable.
|
|
24
|
+
* The card offers approval and a return to the composer for change requests.
|
|
25
|
+
* It accepts one question carrying the plan as detail and the named approve
|
|
26
|
+
* option, with at most one alternative and no multi-select. Larger choices
|
|
27
|
+
* remain in the generic question flow.
|
|
34
28
|
*
|
|
35
29
|
* @param questions - the request's whole question batch.
|
|
36
30
|
* @returns The narrowed review, or undefined when the generic flow owns it.
|
|
@@ -50,6 +44,7 @@ window.__ModuleLoader__.load({
|
|
|
50
44
|
id: question.id,
|
|
51
45
|
question: question.question,
|
|
52
46
|
plan: question.detail,
|
|
47
|
+
...intent.callId === void 0 ? {} : { callId: intent.callId },
|
|
53
48
|
approve,
|
|
54
49
|
...decline === void 0 ? {} : { decline }
|
|
55
50
|
};
|
|
@@ -205,7 +200,7 @@ window.__ModuleLoader__.load({
|
|
|
205
200
|
}
|
|
206
201
|
//#endregion
|
|
207
202
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-user-questions/src/client/PlanReviewPanel.module.css.mjs
|
|
208
|
-
const css$1 = ".LVzXQa_frame{padding:6px calc(var(--dsh-composer-side-clearance) + 16px) 10px;justify-content:center;display:flex}.LVzXQa_card{width:100%;max-width:var(--dsh-chat-content-width)
|
|
203
|
+
const css$1 = ".LVzXQa_frame{padding:6px calc(var(--dsh-composer-side-clearance) + 16px) 10px;justify-content:center;display:flex}.LVzXQa_card{width:100%;max-width:var(--dsh-chat-content-width);--dsw-elevation-stroke-color:var(--dsw-alias-border-l2);background:var(--dsw-specific-input-major);box-shadow:var(--dsw-elevation-panel);color:var(--dsw-alias-label-primary);border:0;border-radius:20px;flex-direction:column;display:flex;overflow:hidden}.LVzXQa_card,.LVzXQa_card *{box-sizing:border-box}.LVzXQa_strip{background:var(--dsw-alias-state-warn-tertiary);color:var(--dsw-alias-state-warn-primary);flex-shrink:0;align-items:center;gap:8px;padding:12px 16px;font-size:14px;line-height:20px;display:flex}.LVzXQa_dot{corner-shape:round;background:var(--dsw-alias-state-warn-primary);border-radius:50%;width:8px;height:8px}.LVzXQa_footer{flex-shrink:0;justify-content:space-between;align-items:center;gap:12px;padding:8px 16px 12px;display:flex}.LVzXQa_feedback{min-height:16px;color:var(--dsw-alias-state-error-primary);font-size:11px;line-height:16px}.LVzXQa_actions{flex-shrink:0;align-items:center;gap:8px;display:flex}.LVzXQa_summary{min-width:0;padding:14px 16px 12px}.LVzXQa_title{text-overflow:ellipsis;white-space:nowrap;margin:0;font-size:15px;font-weight:500;line-height:22px;overflow:hidden}.LVzXQa_description{-webkit-line-clamp:2;color:var(--dsw-alias-label-secondary);-webkit-box-orient:vertical;margin:8px 0 0;font-size:14px;line-height:24px;display:-webkit-box;overflow:hidden}.LVzXQa_discuss{gap:6px}@media (width<=720px){.LVzXQa_card{border-radius:16px}.LVzXQa_footer{align-items:flex-end;padding:8px 12px 10px}}.LVzXQa_previewActions{align-items:center;margin-left:auto;display:flex}";
|
|
209
204
|
const tagId$1 = "@deepseek-ai/dsh-client-ui-user-questions/PlanReviewPanel.module.css";
|
|
210
205
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
211
206
|
const tag = document.createElement("style");
|
|
@@ -216,14 +211,17 @@ window.__ModuleLoader__.load({
|
|
|
216
211
|
}
|
|
217
212
|
var PlanReviewPanel_module_css_default = {
|
|
218
213
|
"actions": "LVzXQa_actions",
|
|
219
|
-
"body": "LVzXQa_body",
|
|
220
214
|
"card": "LVzXQa_card",
|
|
215
|
+
"description": "LVzXQa_description",
|
|
221
216
|
"discuss": "LVzXQa_discuss",
|
|
222
217
|
"dot": "LVzXQa_dot",
|
|
223
218
|
"feedback": "LVzXQa_feedback",
|
|
224
219
|
"footer": "LVzXQa_footer",
|
|
225
220
|
"frame": "LVzXQa_frame",
|
|
226
|
-
"
|
|
221
|
+
"previewActions": "LVzXQa_previewActions",
|
|
222
|
+
"strip": "LVzXQa_strip",
|
|
223
|
+
"summary": "LVzXQa_summary",
|
|
224
|
+
"title": "LVzXQa_title"
|
|
227
225
|
};
|
|
228
226
|
//#endregion
|
|
229
227
|
//#region lib/types/client/PlanReviewPanel.js
|
|
@@ -238,19 +236,12 @@ window.__ModuleLoader__.load({
|
|
|
238
236
|
return description === void 0 ? {} : { title: description };
|
|
239
237
|
}
|
|
240
238
|
/**
|
|
241
|
-
* Render
|
|
239
|
+
* Render plan review controls; the submitted document opens in the sidebar.
|
|
242
240
|
*
|
|
243
241
|
* @param props - the question domain face, the narrowed plan review, and `t`.
|
|
244
242
|
* @returns The plan-review takeover for this request.
|
|
245
243
|
*/
|
|
246
|
-
function PlanReviewPanel({ pending, review, t }) {
|
|
247
|
-
const markdownLabels = (0, react.useMemo)(() => ({
|
|
248
|
-
code: {
|
|
249
|
-
copyLabel: t("copy"),
|
|
250
|
-
copiedLabel: t("copied")
|
|
251
|
-
},
|
|
252
|
-
footnotes: t("markdown.footnotes")
|
|
253
|
-
}), [t]);
|
|
244
|
+
function PlanReviewPanel({ pending, review, t, renderSlot }) {
|
|
254
245
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
255
246
|
const [error, setError] = (0, react.useState)(null);
|
|
256
247
|
const settle = (send) => {
|
|
@@ -267,7 +258,14 @@ window.__ModuleLoader__.load({
|
|
|
267
258
|
selected: [label]
|
|
268
259
|
}] }));
|
|
269
260
|
};
|
|
270
|
-
const
|
|
261
|
+
const summary = (0, react.useMemo)(() => {
|
|
262
|
+
const title = (0, _deepseek_ai_dsh_client_ui_primitives.extractMarkdownPlainText)(review.plan, { mode: "first-line" });
|
|
263
|
+
const description = (0, _deepseek_ai_dsh_client_ui_primitives.extractMarkdownPlainText)(review.plan, { mode: "first-paragraph" });
|
|
264
|
+
return {
|
|
265
|
+
title,
|
|
266
|
+
description: description === title ? "" : description
|
|
267
|
+
};
|
|
268
|
+
}, [review.plan]);
|
|
271
269
|
return (0, react_jsx_runtime.jsx)("div", {
|
|
272
270
|
className: PlanReviewPanel_module_css_default.frame,
|
|
273
271
|
"data-plan-review-key": pending.key,
|
|
@@ -277,15 +275,27 @@ window.__ModuleLoader__.load({
|
|
|
277
275
|
children: [
|
|
278
276
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
279
277
|
className: PlanReviewPanel_module_css_default.strip,
|
|
280
|
-
children: [
|
|
278
|
+
children: [
|
|
279
|
+
(0, react_jsx_runtime.jsx)("span", { className: PlanReviewPanel_module_css_default.dot }),
|
|
280
|
+
t("plan.header"),
|
|
281
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
282
|
+
className: PlanReviewPanel_module_css_default.previewActions,
|
|
283
|
+
children: renderSlot("conversation.plan-review.actions", {
|
|
284
|
+
review,
|
|
285
|
+
requestKey: pending.key
|
|
286
|
+
})
|
|
287
|
+
})
|
|
288
|
+
]
|
|
281
289
|
}),
|
|
282
|
-
(0, react_jsx_runtime.
|
|
283
|
-
className: PlanReviewPanel_module_css_default.
|
|
284
|
-
"
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
290
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
291
|
+
className: PlanReviewPanel_module_css_default.summary,
|
|
292
|
+
children: [(0, react_jsx_runtime.jsx)("h3", {
|
|
293
|
+
className: PlanReviewPanel_module_css_default.title,
|
|
294
|
+
children: summary.title
|
|
295
|
+
}), summary.description !== "" && (0, react_jsx_runtime.jsx)("p", {
|
|
296
|
+
className: PlanReviewPanel_module_css_default.description,
|
|
297
|
+
children: summary.description
|
|
298
|
+
})]
|
|
289
299
|
}),
|
|
290
300
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
291
301
|
className: PlanReviewPanel_module_css_default.footer,
|
|
@@ -295,36 +305,24 @@ window.__ModuleLoader__.load({
|
|
|
295
305
|
children: error
|
|
296
306
|
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
297
307
|
className: PlanReviewPanel_module_css_default.actions,
|
|
298
|
-
children: [
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
children: t("plan.decline")
|
|
317
|
-
}),
|
|
318
|
-
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
319
|
-
variant: "primary",
|
|
320
|
-
...tooltip(review.approve.description),
|
|
321
|
-
disabled: busy,
|
|
322
|
-
onClick: () => {
|
|
323
|
-
decide(review.approve.label);
|
|
324
|
-
},
|
|
325
|
-
children: t("plan.approve")
|
|
326
|
-
})
|
|
327
|
-
]
|
|
308
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
309
|
+
variant: "outline",
|
|
310
|
+
className: PlanReviewPanel_module_css_default.discuss,
|
|
311
|
+
icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, { size: 14 }),
|
|
312
|
+
disabled: busy,
|
|
313
|
+
onClick: () => {
|
|
314
|
+
settle(() => pending.cancel());
|
|
315
|
+
},
|
|
316
|
+
children: t("plan.discuss")
|
|
317
|
+
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
318
|
+
variant: "primary",
|
|
319
|
+
...tooltip(review.approve.description),
|
|
320
|
+
disabled: busy,
|
|
321
|
+
onClick: () => {
|
|
322
|
+
decide(review.approve.label);
|
|
323
|
+
},
|
|
324
|
+
children: t("plan.approve")
|
|
325
|
+
})]
|
|
328
326
|
})]
|
|
329
327
|
})
|
|
330
328
|
]
|
|
@@ -460,7 +458,8 @@ window.__ModuleLoader__.load({
|
|
|
460
458
|
}, question.key) : (0, react_jsx_runtime.jsx)(PlanReviewPanel, {
|
|
461
459
|
pending: question,
|
|
462
460
|
review,
|
|
463
|
-
t: props.t
|
|
461
|
+
t: props.t,
|
|
462
|
+
renderSlot: props.renderSlot
|
|
464
463
|
}, question.key);
|
|
465
464
|
}
|
|
466
465
|
function QuestionFlow({ pending, t, useStore, actions }) {
|
|
@@ -802,9 +801,9 @@ window.__ModuleLoader__.load({
|
|
|
802
801
|
"action.skip": "跳过",
|
|
803
802
|
"action.next": "下一题",
|
|
804
803
|
"plan.header": "计划待审",
|
|
805
|
-
"plan.approve": "
|
|
804
|
+
"plan.approve": "同意执行",
|
|
806
805
|
"plan.decline": "拒绝",
|
|
807
|
-
"plan.discuss": "
|
|
806
|
+
"plan.discuss": "要求修改"
|
|
808
807
|
};
|
|
809
808
|
/** English dictionary, checked complete against the zh key set. */
|
|
810
809
|
const en = {
|
|
@@ -822,7 +821,7 @@ window.__ModuleLoader__.load({
|
|
|
822
821
|
"plan.header": "Plan review",
|
|
823
822
|
"plan.approve": "Approve",
|
|
824
823
|
"plan.decline": "Refuse",
|
|
825
|
-
"plan.discuss": "
|
|
824
|
+
"plan.discuss": "Request changes"
|
|
826
825
|
};
|
|
827
826
|
//#endregion
|
|
828
827
|
//#region lib/types/client/index.js
|
|
@@ -875,7 +874,11 @@ window.__ModuleLoader__.load({
|
|
|
875
874
|
name: "conversation.composer",
|
|
876
875
|
select: ({ pendingInteraction }) => pendingInteraction instanceof PendingQuestion ? pendingInteraction : null,
|
|
877
876
|
locale: NS,
|
|
878
|
-
store: questionDraftStore
|
|
877
|
+
store: questionDraftStore,
|
|
878
|
+
children: { "conversation.plan-review.actions": {
|
|
879
|
+
kind: "list",
|
|
880
|
+
scope: "session"
|
|
881
|
+
} }
|
|
879
882
|
}, QuestionComposer));
|
|
880
883
|
ctx.remote.$on("user-questions/request", function(request, next) {
|
|
881
884
|
return answerQuestion(ctx, this, request, next, registerPendingInteraction);
|
|
@@ -3,12 +3,12 @@ import type { PendingQuestion, PlanReview, QuestionComposerProps } from './contr
|
|
|
3
3
|
export type PlanReviewPanelProps = {
|
|
4
4
|
pending: PendingQuestion;
|
|
5
5
|
review: PlanReview;
|
|
6
|
-
} & Pick<QuestionComposerProps, 't'>;
|
|
6
|
+
} & Pick<QuestionComposerProps, 't' | 'renderSlot'>;
|
|
7
7
|
/**
|
|
8
|
-
* Render
|
|
8
|
+
* Render plan review controls; the submitted document opens in the sidebar.
|
|
9
9
|
*
|
|
10
10
|
* @param props - the question domain face, the narrowed plan review, and `t`.
|
|
11
11
|
* @returns The plan-review takeover for this request.
|
|
12
12
|
*/
|
|
13
|
-
export declare function PlanReviewPanel({ pending, review, t }: PlanReviewPanelProps): import("react").JSX.Element;
|
|
13
|
+
export declare function PlanReviewPanel({ pending, review, t, renderSlot }: PlanReviewPanelProps): import("react").JSX.Element;
|
|
14
14
|
//# sourceMappingURL=PlanReviewPanel.d.ts.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** Question composer props and one pending Remote waterfall response. */
|
|
2
|
-
import type { PropsLocale, PropsRuntime, PropsStore } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import type { PropsLocale, PropsRenderSlots, PropsRuntime, PropsStore } from '@deepseek-ai/dsh-client-ui-slots';
|
|
3
|
+
import type { ToolCallId } from '@deepseek-ai/dsh-llm/brand';
|
|
3
4
|
import type { SessionId } from '@deepseek-ai/dsh-session/types';
|
|
4
5
|
import type { AskUserQuestionAnswer, AskUserQuestionItem } from '@deepseek-ai/dsh-user-questions';
|
|
5
6
|
import type { createQuestionDraftStore } from '../draft-store.ts';
|
|
@@ -9,6 +10,19 @@ declare module '@deepseek-ai/dsh-client-ui-session/client' {
|
|
|
9
10
|
question: PendingQuestion;
|
|
10
11
|
}
|
|
11
12
|
}
|
|
13
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
14
|
+
interface SlotMap {
|
|
15
|
+
/** Actions for the exact plan under review; approval remains with the question composer. */
|
|
16
|
+
'conversation.plan-review.actions': {
|
|
17
|
+
kind: 'list';
|
|
18
|
+
scope: 'session';
|
|
19
|
+
owner: {
|
|
20
|
+
review: PlanReview;
|
|
21
|
+
requestKey: PendingQuestion['key'];
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
12
26
|
/** One structured answer batch covering every question of the request. */
|
|
13
27
|
export type QuestionAnswer = AskUserQuestionAnswer;
|
|
14
28
|
/** One question of the request. */
|
|
@@ -29,6 +43,8 @@ export interface PlanReview {
|
|
|
29
43
|
question: string;
|
|
30
44
|
/** The plan markdown under review. */
|
|
31
45
|
plan: string;
|
|
46
|
+
/** Logged tool invocation used to reopen this plan. */
|
|
47
|
+
callId?: ToolCallId;
|
|
32
48
|
/** The option that approves the plan. */
|
|
33
49
|
approve: QuestionOption;
|
|
34
50
|
/** The option that declines it; absent when the asker offered no other option. */
|
|
@@ -38,16 +54,10 @@ export interface PlanReview {
|
|
|
38
54
|
* Narrow a request to a renderable plan review, or return undefined to leave it
|
|
39
55
|
* to the generic question flow.
|
|
40
56
|
*
|
|
41
|
-
* The card
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* label the intent names, and is a binary single choice: at most one option
|
|
46
|
-
* besides approve, and not multi-select. A third option or a multi-select batch
|
|
47
|
-
* has answers two buttons cannot express, so the generic flow keeps it — as it
|
|
48
|
-
* keeps any request whose intent the asker's own service would have rejected,
|
|
49
|
-
* because the client sits downstream of a wire boundary and every request must
|
|
50
|
-
* stay answerable.
|
|
57
|
+
* The card offers approval and a return to the composer for change requests.
|
|
58
|
+
* It accepts one question carrying the plan as detail and the named approve
|
|
59
|
+
* option, with at most one alternative and no multi-select. Larger choices
|
|
60
|
+
* remain in the generic question flow.
|
|
51
61
|
*
|
|
52
62
|
* @param questions - the request's whole question batch.
|
|
53
63
|
* @returns The narrowed review, or undefined when the generic flow owns it.
|
|
@@ -102,7 +112,7 @@ export type QuestionWait = PendingQuestion;
|
|
|
102
112
|
* standard locale seat; the carrier plus the domain face above carry the
|
|
103
113
|
* whole behavior surface.
|
|
104
114
|
*/
|
|
105
|
-
export type QuestionComposerProps = PropsRuntime<'conversation.composer'> & PropsStore<ReturnType<typeof createQuestionDraftStore>> & {
|
|
115
|
+
export type QuestionComposerProps = PropsRuntime<'conversation.composer'> & PropsStore<ReturnType<typeof createQuestionDraftStore>> & PropsRenderSlots<'conversation.plan-review.actions'> & {
|
|
106
116
|
matched: QuestionWait;
|
|
107
117
|
} & PropsLocale<'question'>;
|
|
108
118
|
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-ui-user-questions",
|
|
3
3
|
"description": "Web ask_user_question composer takeover and plan-review presentation UI",
|
|
4
|
-
"version": "0.1.6-alpha.
|
|
4
|
+
"version": "0.1.6-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -46,23 +46,24 @@
|
|
|
46
46
|
"@types/react": "~18.3.1",
|
|
47
47
|
"react": "^18.2.0",
|
|
48
48
|
"clsx": "^2.0.0",
|
|
49
|
+
"@deepseek-ai/dsh-agent": "^0.1.6-alpha.2",
|
|
49
50
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
50
|
-
"@deepseek-ai/dsh-api-remotes": "^0.1.6-alpha.
|
|
51
|
-
"@deepseek-ai/dsh-api-session-controller": "^0.1.6-alpha.
|
|
52
|
-
"@deepseek-ai/dsh-
|
|
53
|
-
"@deepseek-ai/dsh-client-
|
|
54
|
-
"@deepseek-ai/dsh-
|
|
55
|
-
"@deepseek-ai/dsh-
|
|
56
|
-
"@deepseek-ai/dsh-
|
|
57
|
-
"@deepseek-ai/dsh-
|
|
58
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.1.6-alpha.
|
|
59
|
-
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.6-alpha.
|
|
60
|
-
"@deepseek-ai/dsh-client-ui-
|
|
61
|
-
"@deepseek-ai/dsh-
|
|
62
|
-
"@deepseek-ai/dsh-client-
|
|
63
|
-
"@deepseek-ai/dsh-session": "^0.1.6-alpha.
|
|
64
|
-
"@deepseek-ai/dsh-
|
|
65
|
-
"@deepseek-ai/dsh-client-
|
|
51
|
+
"@deepseek-ai/dsh-api-remotes": "^0.1.6-alpha.2",
|
|
52
|
+
"@deepseek-ai/dsh-api-session-controller": "^0.1.6-alpha.2",
|
|
53
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.6-alpha.2",
|
|
54
|
+
"@deepseek-ai/dsh-client-store": "^0.1.6-alpha.2",
|
|
55
|
+
"@deepseek-ai/dsh-system-prompt": "^0.1.6-alpha.2",
|
|
56
|
+
"@deepseek-ai/dsh-tools": "^0.1.6-alpha.2",
|
|
57
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.6-alpha.2",
|
|
58
|
+
"@deepseek-ai/dsh-user-questions": "^0.1.6-alpha.2",
|
|
59
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.6-alpha.2",
|
|
60
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.6-alpha.2",
|
|
61
|
+
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.6-alpha.2",
|
|
62
|
+
"@deepseek-ai/dsh-llm": "^0.1.6-alpha.2",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-session": "^0.1.6-alpha.2",
|
|
64
|
+
"@deepseek-ai/dsh-session": "^0.1.6-alpha.2",
|
|
65
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.6-alpha.2",
|
|
66
|
+
"@deepseek-ai/dsh-client-connection": "^0.1.6-alpha.2"
|
|
66
67
|
},
|
|
67
68
|
"files": [
|
|
68
69
|
"lib/index.js",
|