@deepseek-ai/dsh-client-ui-chat 0.1.3-alpha.2 → 0.1.5-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +3 -5
- package/README.zh.md +3 -3
- package/lib/client.js +433 -398
- package/lib/types/client/chat/AssistantMarkdown.d.ts +11 -0
- package/lib/types/client/chat/ChatNodeSeat.d.ts +1 -1
- package/lib/types/client/chat/ReasoningRow.d.ts +3 -1
- package/lib/types/client/chat/{StatsLine.d.ts → StatsPills.d.ts} +3 -3
- package/lib/types/client/chat/SystemPromptRow.d.ts +6 -3
- package/lib/types/client/chat/stat-dialog.d.ts +22 -0
- package/lib/types/client/contract/slots.d.ts +9 -27
- package/lib/types/client/contract/snapshot.d.ts +1 -1
- package/lib/types/client/contract/store.d.ts +1 -9
- package/lib/types/client/conversation-nodes/request-prompt.d.ts +18 -4
- package/lib/types/client/conversation-nodes/tool.d.ts +1 -1
- package/lib/types/client/index.d.ts +2 -2
- package/lib/types/client/locale.d.ts +14 -28
- package/lib/types/client/model/tool-call-tree.d.ts +2 -2
- package/lib/types/client/stores.d.ts +3 -4
- package/package.json +32 -28
- package/lib/types/client/details/DetailsPanel.d.ts +0 -4
- package/lib/types/client/details/tool-node-reader.d.ts +0 -9
package/lib/client.js
CHANGED
|
@@ -9,6 +9,40 @@ window.__ModuleLoader__.load({
|
|
|
9
9
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
10
10
|
let _deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
|
|
11
11
|
let react_dom = require("react-dom");
|
|
12
|
+
//#region ../../util/workspace-path/src/file-address.ts
|
|
13
|
+
/** The scheme and type every file address opens with. */
|
|
14
|
+
const FILE_ADDRESS_PREFIX = "dsh-resource://file/";
|
|
15
|
+
/** Component-encode one id or path segment, keeping `:` literal for drive letters. */
|
|
16
|
+
function encodeSegment(segment) {
|
|
17
|
+
return encodeURIComponent(segment).replace(/%3A/gi, ":");
|
|
18
|
+
}
|
|
19
|
+
/** Encode a `/`-separated path segment by segment. */
|
|
20
|
+
function encodePath(path) {
|
|
21
|
+
return path.split("/").map(encodeSegment).join("/");
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build the address of a file inside one Session's workspace.
|
|
25
|
+
* @param sessionId - the Session whose workspace root the path is relative to.
|
|
26
|
+
* @param path - workspace-relative path; backslashes are normalized to `/`, and a leading `./` or `/` is dropped.
|
|
27
|
+
* @returns the `dsh-resource://file/session/<sessionId>/<path>` address.
|
|
28
|
+
*/
|
|
29
|
+
function sessionFileAddress(sessionId, path) {
|
|
30
|
+
const relative = path.replace(/\\/g, "/").replace(/^(?:\.\/)+/, "").replace(/^\/+/, "");
|
|
31
|
+
return `${FILE_ADDRESS_PREFIX}session/${encodeSegment(sessionId)}/${encodePath(relative)}`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build the address of a file by its absolute path.
|
|
35
|
+
* @param path - absolute path; backslashes are normalized to `/` and the leading `/` is dropped,
|
|
36
|
+
* except that a UNC path (`\\server\share`) keeps one empty first segment.
|
|
37
|
+
* @returns the `dsh-resource://file/absolute/<path>` address.
|
|
38
|
+
*/
|
|
39
|
+
function absoluteFileAddress(path) {
|
|
40
|
+
const normalized = path.replace(/\\/g, "/");
|
|
41
|
+
const unc = normalized.startsWith("//");
|
|
42
|
+
const absolute = normalized.replace(/^\/+/, "");
|
|
43
|
+
return `${FILE_ADDRESS_PREFIX}absolute/${unc ? "/" : ""}${encodePath(absolute)}`;
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
12
46
|
//#region ../../util/workspace-path/src/index.ts
|
|
13
47
|
/**
|
|
14
48
|
* Browser-safe Workspace path and display helpers.
|
|
@@ -19,16 +53,30 @@ window.__ModuleLoader__.load({
|
|
|
19
53
|
return /^[A-Za-z]:[/\\]/.test(value) || value.startsWith("\\\\");
|
|
20
54
|
}
|
|
21
55
|
/**
|
|
22
|
-
*
|
|
23
|
-
* @param
|
|
24
|
-
* @
|
|
25
|
-
|
|
56
|
+
* Whether a path is absolute in either spelling the Host accepts: POSIX (`/a/b`) or Windows drive or UNC.
|
|
57
|
+
* @param path - the path to classify.
|
|
58
|
+
* @returns `true` for an absolute path; `false` for a Workspace-relative one.
|
|
59
|
+
*/
|
|
60
|
+
function isAbsoluteWorkspacePath(path) {
|
|
61
|
+
return path.startsWith("/") || isWindowsStylePath(path);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The address for a path as a caller holds it: a relative path, or an absolute
|
|
65
|
+
* path inside the Session's workspace, becomes a `session`-scoped address; an
|
|
66
|
+
* absolute path outside it, or one whose workspace root is unknown, becomes an
|
|
67
|
+
* `absolute`-scoped address.
|
|
68
|
+
* @param sessionId - the Session the path is read in.
|
|
69
|
+
* @param cwd - that Session's workspace root, when known.
|
|
70
|
+
* @param path - absolute or workspace-relative path, in either separator spelling.
|
|
71
|
+
* @returns the `dsh-resource://file/…` address.
|
|
26
72
|
*/
|
|
27
|
-
function
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
const
|
|
31
|
-
|
|
73
|
+
function fileAddressFor(sessionId, cwd, path) {
|
|
74
|
+
const normalized = path.replace(/\\/g, "/");
|
|
75
|
+
if (!isAbsoluteWorkspacePath(normalized)) return sessionFileAddress(sessionId, normalized);
|
|
76
|
+
const root = cwd === void 0 ? "" : cwd.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
77
|
+
if (root !== "" && normalized === root) return sessionFileAddress(sessionId, "");
|
|
78
|
+
if (root !== "" && normalized.startsWith(`${root}/`)) return sessionFileAddress(sessionId, normalized.slice(root.length + 1));
|
|
79
|
+
return absoluteFileAddress(normalized);
|
|
32
80
|
}
|
|
33
81
|
//#endregion
|
|
34
82
|
//#region lib/types/client/contract/snapshot.js
|
|
@@ -1407,7 +1455,7 @@ window.__ModuleLoader__.load({
|
|
|
1407
1455
|
}
|
|
1408
1456
|
//#endregion
|
|
1409
1457
|
//#region lib/types/client/stores.js
|
|
1410
|
-
/** Per-Session Chat
|
|
1458
|
+
/** Per-Session Chat view store. */
|
|
1411
1459
|
/**
|
|
1412
1460
|
* Resolve the manually expanded answer for one Turn.
|
|
1413
1461
|
* @param state - Chat store snapshot.
|
|
@@ -1418,33 +1466,25 @@ window.__ModuleLoader__.load({
|
|
|
1418
1466
|
return state.turnProcesses.find((entry) => entry.turn === turn);
|
|
1419
1467
|
}
|
|
1420
1468
|
/**
|
|
1421
|
-
* Create the Chat
|
|
1469
|
+
* Create the Chat view store handle.
|
|
1422
1470
|
* @returns a handle instantiated once per rendered Session scope.
|
|
1423
1471
|
*/
|
|
1424
1472
|
function createChatStore() {
|
|
1425
1473
|
return (0, _deepseek_ai_dsh_client_store.defineStore)({
|
|
1426
|
-
init: () => ({
|
|
1427
|
-
|
|
1428
|
-
turnProcesses
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
draft.selection = target;
|
|
1433
|
-
},
|
|
1434
|
-
setTurnProcessOpen: (draft, turn, answerStep, open) => {
|
|
1435
|
-
const index = draft.turnProcesses.findIndex((entry) => entry.turn === turn);
|
|
1436
|
-
if (!open) {
|
|
1437
|
-
if (index >= 0) draft.turnProcesses.splice(index, 1);
|
|
1438
|
-
return;
|
|
1439
|
-
}
|
|
1440
|
-
const next = {
|
|
1441
|
-
turn,
|
|
1442
|
-
answerStep
|
|
1443
|
-
};
|
|
1444
|
-
if (index < 0) draft.turnProcesses.push(next);
|
|
1445
|
-
else draft.turnProcesses[index] = next;
|
|
1474
|
+
init: () => ({ turnProcesses: [] }),
|
|
1475
|
+
actions: { setTurnProcessOpen: (draft, turn, answerStep, open) => {
|
|
1476
|
+
const index = draft.turnProcesses.findIndex((entry) => entry.turn === turn);
|
|
1477
|
+
if (!open) {
|
|
1478
|
+
if (index >= 0) draft.turnProcesses.splice(index, 1);
|
|
1479
|
+
return;
|
|
1446
1480
|
}
|
|
1447
|
-
|
|
1481
|
+
const next = {
|
|
1482
|
+
turn,
|
|
1483
|
+
answerStep
|
|
1484
|
+
};
|
|
1485
|
+
if (index < 0) draft.turnProcesses.push(next);
|
|
1486
|
+
else draft.turnProcesses[index] = next;
|
|
1487
|
+
} }
|
|
1448
1488
|
});
|
|
1449
1489
|
}
|
|
1450
1490
|
//#endregion
|
|
@@ -1515,7 +1555,7 @@ window.__ModuleLoader__.load({
|
|
|
1515
1555
|
return location?.kind === "turn" || location?.kind === "step" ? location.turn.turn : void 0;
|
|
1516
1556
|
}
|
|
1517
1557
|
/** Subscribe, apply Turn-process visibility, and dispatch one stable Context key. */
|
|
1518
|
-
const ChatNodeSeat = (0, react.memo)(function ChatNodeSeat({ nodeKey, useChatNode, useChatNodeProcess, historyIncomplete, compactTranscript,
|
|
1558
|
+
const ChatNodeSeat = (0, react.memo)(function ChatNodeSeat({ nodeKey, useChatNode, useChatNodeProcess, historyIncomplete, compactTranscript, cwd, openFile, inspectCall, forkAt, loadImage, renderMessageImages, fileMentions, useStore, actions, renderSlot, t }) {
|
|
1519
1559
|
const node = useChatNode(nodeKey);
|
|
1520
1560
|
const routedNode = node;
|
|
1521
1561
|
const turn = turnOf(routedNode);
|
|
@@ -1549,7 +1589,6 @@ window.__ModuleLoader__.load({
|
|
|
1549
1589
|
if (processMember) setOpen(true);
|
|
1550
1590
|
}, [processMember, setOpen]));
|
|
1551
1591
|
const owner = (0, react.useMemo)(() => node === void 0 ? null : {
|
|
1552
|
-
selectedCallId,
|
|
1553
1592
|
cwd,
|
|
1554
1593
|
openFile,
|
|
1555
1594
|
inspectCall,
|
|
@@ -1560,7 +1599,6 @@ window.__ModuleLoader__.load({
|
|
|
1560
1599
|
turnProcess
|
|
1561
1600
|
}, [
|
|
1562
1601
|
node,
|
|
1563
|
-
selectedCallId,
|
|
1564
1602
|
cwd,
|
|
1565
1603
|
openFile,
|
|
1566
1604
|
inspectCall,
|
|
@@ -1985,10 +2023,6 @@ window.__ModuleLoader__.load({
|
|
|
1985
2023
|
const message = error instanceof Error ? error.message : String(error);
|
|
1986
2024
|
return message === "" ? fallback : message;
|
|
1987
2025
|
}
|
|
1988
|
-
/** ProducedFiles opens the session workspace as `.`. */
|
|
1989
|
-
function isFolderOpenPath(path) {
|
|
1990
|
-
return path === ".";
|
|
1991
|
-
}
|
|
1992
2026
|
/**
|
|
1993
2027
|
* Prompt-RPC identities already rendered by durable material: user/steering
|
|
1994
2028
|
* node sources plus queue occurrences. A submission echo whose identity
|
|
@@ -2063,7 +2097,6 @@ window.__ModuleLoader__.load({
|
|
|
2063
2097
|
const openError = useSession((s) => s.openError);
|
|
2064
2098
|
const hasMore = useSession((s) => s.hasMore);
|
|
2065
2099
|
const loadingOlder = useSession((s) => s.loadingOlder);
|
|
2066
|
-
const selectedCallId = useStore((s) => s.selection?.callId);
|
|
2067
2100
|
const compactTranscript = useTranscriptView((mode) => mode === "compact");
|
|
2068
2101
|
const inspectCall = (0, react.useCallback)((callId) => {
|
|
2069
2102
|
openView("trajectory", callId);
|
|
@@ -2071,10 +2104,10 @@ window.__ModuleLoader__.load({
|
|
|
2071
2104
|
const [fileOpenError, setFileOpenError] = (0, react.useState)(null);
|
|
2072
2105
|
const [fileOpenBusy, setFileOpenBusy] = (0, react.useState)(false);
|
|
2073
2106
|
const fileOpenRequest = (0, react.useRef)(0);
|
|
2074
|
-
const requestOpenFile = (0, react.useCallback)((path) => {
|
|
2107
|
+
const requestOpenFile = (0, react.useCallback)((path, options) => {
|
|
2075
2108
|
const id = ++fileOpenRequest.current;
|
|
2076
2109
|
setFileOpenBusy(true);
|
|
2077
|
-
openFile(path).then(() => {
|
|
2110
|
+
(options === void 0 ? openFile(path) : openFile(path, options)).then(() => {
|
|
2078
2111
|
if (id !== fileOpenRequest.current) return;
|
|
2079
2112
|
setFileOpenError(null);
|
|
2080
2113
|
setFileOpenBusy(false);
|
|
@@ -2082,7 +2115,7 @@ window.__ModuleLoader__.load({
|
|
|
2082
2115
|
if (id !== fileOpenRequest.current) return;
|
|
2083
2116
|
setFileOpenError({
|
|
2084
2117
|
path,
|
|
2085
|
-
message: openFailureMessage(error, t(
|
|
2118
|
+
message: openFailureMessage(error, t("fileOpen.unknown"))
|
|
2086
2119
|
});
|
|
2087
2120
|
setFileOpenBusy(false);
|
|
2088
2121
|
});
|
|
@@ -2521,7 +2554,6 @@ window.__ModuleLoader__.load({
|
|
|
2521
2554
|
compactTranscript,
|
|
2522
2555
|
useStore,
|
|
2523
2556
|
actions,
|
|
2524
|
-
selectedCallId,
|
|
2525
2557
|
cwd,
|
|
2526
2558
|
openFile: requestOpenFile,
|
|
2527
2559
|
inspectCall,
|
|
@@ -2564,7 +2596,6 @@ window.__ModuleLoader__.load({
|
|
|
2564
2596
|
})
|
|
2565
2597
|
]
|
|
2566
2598
|
}), fileOpenError !== null && (0, react_jsx_runtime.jsx)(FileOpenErrorDialog, {
|
|
2567
|
-
path: fileOpenError.path,
|
|
2568
2599
|
message: fileOpenError.message,
|
|
2569
2600
|
busy: fileOpenBusy,
|
|
2570
2601
|
onClose: closeFileOpenError,
|
|
@@ -2576,12 +2607,12 @@ window.__ModuleLoader__.load({
|
|
|
2576
2607
|
});
|
|
2577
2608
|
}
|
|
2578
2609
|
/** In-page Host open-path refusal: the wire reason plus a retry of the same path. */
|
|
2579
|
-
function FileOpenErrorDialog({
|
|
2610
|
+
function FileOpenErrorDialog({ message, busy, onClose, onRetry, t }) {
|
|
2580
2611
|
return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
2581
2612
|
open: true,
|
|
2582
2613
|
onClose,
|
|
2583
2614
|
closeLabel: t("close"),
|
|
2584
|
-
title: t(
|
|
2615
|
+
title: t("fileOpen.title"),
|
|
2585
2616
|
description: message,
|
|
2586
2617
|
footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2587
2618
|
variant: "outline",
|
|
@@ -2609,20 +2640,14 @@ window.__ModuleLoader__.load({
|
|
|
2609
2640
|
"duration.compactSeconds": "{seconds}秒",
|
|
2610
2641
|
"duration.compactMinutes": "{minutes}分{seconds}秒",
|
|
2611
2642
|
"duration.milliseconds": "{milliseconds}毫秒",
|
|
2612
|
-
"stats.counts": "{turns} 轮
|
|
2613
|
-
"stats.llm": "LLM {duration}",
|
|
2614
|
-
"stats.toolCall": "工具调用 {duration}",
|
|
2615
|
-
"stats.ttftAverage": "首 token 平均 {duration}",
|
|
2616
|
-
"stats.tokensPerSecond": "{throughput} tok/s",
|
|
2643
|
+
"stats.counts": "{turns} 轮 {steps} 步",
|
|
2617
2644
|
"stats.cacheHit": "缓存命中 {percent}%",
|
|
2618
|
-
"stats.
|
|
2619
|
-
"
|
|
2620
|
-
"
|
|
2621
|
-
"
|
|
2622
|
-
"
|
|
2623
|
-
"
|
|
2624
|
-
"details.output": "输出",
|
|
2625
|
-
"details.running": "运行中…",
|
|
2645
|
+
"stats.dialog.title": "会话统计",
|
|
2646
|
+
"stats.dialog.usageTitle": "Token 用量",
|
|
2647
|
+
"stats.dialog.llmTime": "模型用时",
|
|
2648
|
+
"stats.dialog.toolTime": "工具调用用时",
|
|
2649
|
+
"stats.dialog.ttft": "首 token 平均(TTFT)",
|
|
2650
|
+
"stats.dialog.speed": "输出速度(TPS)",
|
|
2626
2651
|
"chat.loadingHistory": "载入历史…",
|
|
2627
2652
|
"chat.loadError": "历史加载失败:{message}({code})",
|
|
2628
2653
|
"chat.loadOlder": "加载更早",
|
|
@@ -2638,10 +2663,9 @@ window.__ModuleLoader__.load({
|
|
|
2638
2663
|
"settings.transcript.compact": "Compact",
|
|
2639
2664
|
"fileOpen.title": "无法打开文件",
|
|
2640
2665
|
"fileOpen.unknown": "无法打开此文件",
|
|
2641
|
-
"fileOpen.folderTitle": "无法打开文件夹",
|
|
2642
|
-
"fileOpen.folderUnknown": "无法打开此文件夹",
|
|
2643
2666
|
"message.extraBlock": "附加内容块",
|
|
2644
2667
|
"message.systemPrompt": "系统提示词",
|
|
2668
|
+
"message.systemPromptUpdate": "系统提示词更新",
|
|
2645
2669
|
"message.contextInjection": "上下文注入",
|
|
2646
2670
|
"message.contextRecall": "跨会话召回",
|
|
2647
2671
|
"message.referenceSummary": "引用会话 · {labels}",
|
|
@@ -2722,20 +2746,14 @@ window.__ModuleLoader__.load({
|
|
|
2722
2746
|
"duration.compactSeconds": "{seconds}s",
|
|
2723
2747
|
"duration.compactMinutes": "{minutes}m{seconds}s",
|
|
2724
2748
|
"duration.milliseconds": "{milliseconds}ms",
|
|
2725
|
-
"stats.counts": "{turns} turns
|
|
2726
|
-
"stats.llm": "LLM {duration}",
|
|
2727
|
-
"stats.toolCall": "Tool call {duration}",
|
|
2728
|
-
"stats.ttftAverage": "TTFT avg {duration}",
|
|
2729
|
-
"stats.tokensPerSecond": "{throughput} tok/s",
|
|
2749
|
+
"stats.counts": "{turns} turns {steps} steps",
|
|
2730
2750
|
"stats.cacheHit": "Cache hit {percent}%",
|
|
2731
|
-
"stats.
|
|
2732
|
-
"
|
|
2733
|
-
"
|
|
2734
|
-
"
|
|
2735
|
-
"
|
|
2736
|
-
"
|
|
2737
|
-
"details.output": "Output",
|
|
2738
|
-
"details.running": "Running…",
|
|
2751
|
+
"stats.dialog.title": "Session statistics",
|
|
2752
|
+
"stats.dialog.usageTitle": "Token usage",
|
|
2753
|
+
"stats.dialog.llmTime": "LLM time",
|
|
2754
|
+
"stats.dialog.toolTime": "Tool time",
|
|
2755
|
+
"stats.dialog.ttft": "Avg time to first token (TTFT)",
|
|
2756
|
+
"stats.dialog.speed": "Tokens per second (TPS)",
|
|
2739
2757
|
"chat.loadingHistory": "Loading history…",
|
|
2740
2758
|
"chat.loadError": "Failed to load history: {message} ({code})",
|
|
2741
2759
|
"chat.loadOlder": "Load earlier",
|
|
@@ -2751,10 +2769,9 @@ window.__ModuleLoader__.load({
|
|
|
2751
2769
|
"settings.transcript.compact": "Compact",
|
|
2752
2770
|
"fileOpen.title": "Couldn’t open file",
|
|
2753
2771
|
"fileOpen.unknown": "Couldn’t open this file",
|
|
2754
|
-
"fileOpen.folderTitle": "Couldn’t open folder",
|
|
2755
|
-
"fileOpen.folderUnknown": "Couldn’t open this folder",
|
|
2756
2772
|
"message.extraBlock": "Extra content block",
|
|
2757
2773
|
"message.systemPrompt": "System prompt",
|
|
2774
|
+
"message.systemPromptUpdate": "System prompt update",
|
|
2758
2775
|
"message.contextInjection": "Context injection",
|
|
2759
2776
|
"message.contextRecall": "Session recall",
|
|
2760
2777
|
"message.referenceSummary": "Referenced session · {labels}",
|
|
@@ -2876,7 +2893,9 @@ window.__ModuleLoader__.load({
|
|
|
2876
2893
|
return newline === -1 ? visible : visible.slice(newline + 1);
|
|
2877
2894
|
}
|
|
2878
2895
|
/**
|
|
2879
|
-
* Render one assistant reasoning block as the Think disclosure row.
|
|
2896
|
+
* Render one assistant reasoning block as the Think disclosure row. The
|
|
2897
|
+
* collapsed summary omits double-asterisk markers; expanded content preserves
|
|
2898
|
+
* the complete text.
|
|
2880
2899
|
* @param props.text - complete or streaming reasoning text.
|
|
2881
2900
|
* @param props.running - whether this block is the streaming tail.
|
|
2882
2901
|
* @param props.t - conversation locale seat for the running status.
|
|
@@ -2884,7 +2903,7 @@ window.__ModuleLoader__.load({
|
|
|
2884
2903
|
*/
|
|
2885
2904
|
function ReasoningRow({ text, running, t }) {
|
|
2886
2905
|
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
2887
|
-
const summary = running ? latestLine(text) : firstLine(text);
|
|
2906
|
+
const summary = (running ? latestLine(text) : firstLine(text)).replaceAll("**", "");
|
|
2888
2907
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
2889
2908
|
className: ReasoningRow_module_css_default.root,
|
|
2890
2909
|
"data-variant": "think",
|
|
@@ -2943,9 +2962,28 @@ window.__ModuleLoader__.load({
|
|
|
2943
2962
|
};
|
|
2944
2963
|
//#endregion
|
|
2945
2964
|
//#region lib/types/client/chat/AssistantMarkdown.js
|
|
2965
|
+
/**
|
|
2966
|
+
* Map one authored media destination to the same-origin workspace-file URL.
|
|
2967
|
+
* @param protocol - `window.location.protocol` at render time.
|
|
2968
|
+
* @param origin - `window.location.origin` at render time.
|
|
2969
|
+
* @param value - The authored markdown destination, exactly as written.
|
|
2970
|
+
* @returns The API URL for an absolute POSIX path on an HTTP(S) page, or
|
|
2971
|
+
* undefined when the destination cannot be a Host-served local file
|
|
2972
|
+
* (non-HTTP transport such as Electron `file://`, protocol-relative or
|
|
2973
|
+
* relative destinations).
|
|
2974
|
+
*/
|
|
2975
|
+
function localPathMediaUrl(protocol, origin, value) {
|
|
2976
|
+
if (protocol !== "http:" && protocol !== "https:") return void 0;
|
|
2977
|
+
if (value.length === 0 || !value.startsWith("/") || value.startsWith("//")) return void 0;
|
|
2978
|
+
return `${origin}/api/file?path=${encodeURIComponent(value)}`;
|
|
2979
|
+
}
|
|
2946
2980
|
/** Reasoning block as the Think variant summary row (figma 39:28304). */
|
|
2947
2981
|
const AssistantMarkdown = (0, react.memo)(function AssistantMarkdown({ blocks, streaming, interrupted, renderMessageImages, reasoningHidden = false, revealProcess, mentions, t }) {
|
|
2948
2982
|
const labels = (0, react.useMemo)(() => markdownLabels(t), [t]);
|
|
2983
|
+
const pathImages = (0, react.useMemo)(() => {
|
|
2984
|
+
const { protocol, origin } = window.location;
|
|
2985
|
+
return { resolve: (value) => localPathMediaUrl(protocol, origin, value) };
|
|
2986
|
+
}, []);
|
|
2949
2987
|
const last = blocks.length - 1;
|
|
2950
2988
|
if (!(streaming || interrupted === true || blocks.some((block) => block.kind !== "tool-call"))) return null;
|
|
2951
2989
|
const rendered = [];
|
|
@@ -2958,7 +2996,8 @@ window.__ModuleLoader__.load({
|
|
|
2958
2996
|
text: block.text,
|
|
2959
2997
|
streaming,
|
|
2960
2998
|
labels,
|
|
2961
|
-
fileMentions: mentions
|
|
2999
|
+
fileMentions: mentions,
|
|
3000
|
+
pathImages
|
|
2962
3001
|
}, i));
|
|
2963
3002
|
break;
|
|
2964
3003
|
case "reasoning":
|
|
@@ -3190,17 +3229,18 @@ window.__ModuleLoader__.load({
|
|
|
3190
3229
|
/**
|
|
3191
3230
|
* Render one complete system prompt as a collapsed disclosure whose expanded
|
|
3192
3231
|
* body is the same opaque context chrome: 141px code-block scrollport and
|
|
3193
|
-
* model-facing text with its real line breaks.
|
|
3194
|
-
*
|
|
3232
|
+
* model-facing text with its real line breaks. An in-history update uses the
|
|
3233
|
+
* same row under its own title.
|
|
3234
|
+
* @param props - Complete prompt text, whether it is an update, and the locale seat.
|
|
3195
3235
|
* @returns The system-prompt disclosure row.
|
|
3196
3236
|
*/
|
|
3197
|
-
function SystemPromptRow({ text, t }) {
|
|
3237
|
+
function SystemPromptRow({ text, update = false, t }) {
|
|
3198
3238
|
const [open, setOpen] = (0, react.useState)(false);
|
|
3199
3239
|
return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.DisclosureRow, {
|
|
3200
3240
|
className: ContextInjectionRow_module_css_default.root,
|
|
3201
3241
|
icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBrowseOutline16, { size: 14 }),
|
|
3202
3242
|
chevronClassName: ContextInjectionRow_module_css_default.chevron,
|
|
3203
|
-
title: t("message.systemPrompt"),
|
|
3243
|
+
title: t(update ? "message.systemPromptUpdate" : "message.systemPrompt"),
|
|
3204
3244
|
open,
|
|
3205
3245
|
expandable: true,
|
|
3206
3246
|
expandOnRowClick: true,
|
|
@@ -3225,6 +3265,7 @@ window.__ModuleLoader__.load({
|
|
|
3225
3265
|
const SystemPromptNodeView = (0, react.memo)(function SystemPromptNodeView({ node, t }) {
|
|
3226
3266
|
return (0, react_jsx_runtime.jsx)(SystemPromptRow, {
|
|
3227
3267
|
text: node.data.text,
|
|
3268
|
+
update: node.data.update === true,
|
|
3228
3269
|
t
|
|
3229
3270
|
});
|
|
3230
3271
|
});
|
|
@@ -3357,37 +3398,7 @@ window.__ModuleLoader__.load({
|
|
|
3357
3398
|
return `99.${"9".repeat(distinguishingPlaces - 1)}${10 - roundedLoss}`;
|
|
3358
3399
|
}
|
|
3359
3400
|
//#endregion
|
|
3360
|
-
//#region
|
|
3361
|
-
const css$4 = ".Q51KRG_root{min-width:0;display:inline-flex}.Q51KRG_root+.Q51KRG_root{margin-left:-6px}.Q51KRG_trigger{min-width:0;height:calc(28px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-tertiary);font-size:var(--dsh-content-font-size-secondary,13px);font-variant-numeric:tabular-nums;line-height:calc(24px + var(--dsh-content-font-delta,0px));white-space:nowrap;cursor:pointer;background:0 0;border:none;border-radius:28px;align-items:center;gap:4px;padding:6px 8px;display:inline-flex}.Q51KRG_label{text-overflow:ellipsis;min-width:0;overflow:hidden}.Q51KRG_trigger svg{width:calc(15px + var(--dsh-content-font-delta,0px));height:calc(15px + var(--dsh-content-font-delta,0px));flex:none}.Q51KRG_trigger:hover,.Q51KRG_trigger[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary)}@media (width<=480px){.Q51KRG_trigger{width:calc(28px + var(--dsh-content-font-delta,0px));justify-content:center;padding:6px}.Q51KRG_trigger .Q51KRG_label{display:none}.Q51KRG_root+.Q51KRG_root{margin-left:0}}.Q51KRG_panel{z-index:1100;box-sizing:border-box;background:var(--dsw-specific-menu);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);width:max-content;min-width:min(300px,100vw - 24px);max-width:min(440px,100vw - 24px);box-shadow:var(--dsw-elevation-prominent);color:var(--dsw-alias-label-secondary);cursor:default;border:0;border-radius:12px;padding:16px;font-size:12px;line-height:18px;position:fixed}.Q51KRG_title{color:var(--dsw-alias-label-primary);justify-content:space-between;gap:16px;margin-bottom:8px;font-weight:500;display:flex}.Q51KRG_titleRule{border-top:.5px solid var(--dsw-alias-border-l2);margin-bottom:10px}.Q51KRG_titleValue{font-variant-numeric:tabular-nums}.Q51KRG_titleLabel{align-items:center;gap:6px;min-width:0;display:inline-flex}.Q51KRG_titleLabel svg{flex:none;width:14px;height:14px}.Q51KRG_details{color:var(--dsw-alias-label-tertiary);grid-template-columns:minmax(76px,auto) minmax(0,1fr);gap:6px 16px;margin:0;display:grid}.Q51KRG_details dt,.Q51KRG_details dd{min-width:0;margin:0}.Q51KRG_details dd{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;text-align:right}.Q51KRG_details .Q51KRG_route{overflow-wrap:anywhere}.Q51KRG_reasoning{color:var(--dsw-alias-label-tertiary);white-space:nowrap}";
|
|
3362
|
-
const tagId$4 = "@deepseek-ai/dsh-client-ui-chat/TurnUsagePanel.module.css";
|
|
3363
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
|
|
3364
|
-
const tag = document.createElement("style");
|
|
3365
|
-
tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-chat";
|
|
3366
|
-
tag.dataset.pluginCss = tagId$4;
|
|
3367
|
-
tag.textContent = css$4;
|
|
3368
|
-
document.head.appendChild(tag);
|
|
3369
|
-
}
|
|
3370
|
-
var TurnUsagePanel_module_css_default = {
|
|
3371
|
-
"details": "Q51KRG_details",
|
|
3372
|
-
"label": "Q51KRG_label",
|
|
3373
|
-
"panel": "Q51KRG_panel",
|
|
3374
|
-
"reasoning": "Q51KRG_reasoning",
|
|
3375
|
-
"root": "Q51KRG_root",
|
|
3376
|
-
"route": "Q51KRG_route",
|
|
3377
|
-
"title": "Q51KRG_title",
|
|
3378
|
-
"titleLabel": "Q51KRG_titleLabel",
|
|
3379
|
-
"titleRule": "Q51KRG_titleRule",
|
|
3380
|
-
"titleValue": "Q51KRG_titleValue",
|
|
3381
|
-
"trigger": "Q51KRG_trigger"
|
|
3382
|
-
};
|
|
3383
|
-
//#endregion
|
|
3384
|
-
//#region lib/types/client/chat/TurnUsagePanel.js
|
|
3385
|
-
function formatCompactCount(value, t) {
|
|
3386
|
-
return t("message.turnUsage.count", { count: formatTokens(value, t) });
|
|
3387
|
-
}
|
|
3388
|
-
function formatExactCount(value, t) {
|
|
3389
|
-
return t("message.turnUsage.count", { count: formatExactTokens(value, t) });
|
|
3390
|
-
}
|
|
3401
|
+
//#region lib/types/client/chat/stat-dialog.js
|
|
3391
3402
|
/** Viewport margin the placement clamp keeps (the Menu portal margin). */
|
|
3392
3403
|
const PANEL_MARGIN = 12;
|
|
3393
3404
|
/** Distance between the trigger's top edge and the panel's bottom. */
|
|
@@ -3401,9 +3412,16 @@ window.__ModuleLoader__.load({
|
|
|
3401
3412
|
left: 0,
|
|
3402
3413
|
top: 0
|
|
3403
3414
|
};
|
|
3404
|
-
/**
|
|
3405
|
-
|
|
3406
|
-
|
|
3415
|
+
/**
|
|
3416
|
+
* One trigger-anchored dialog seat: open state, viewport-clamped placement, outside-close.
|
|
3417
|
+
* @param controlled - external open state; when given the seat reads and writes
|
|
3418
|
+
* it instead of owning its own, letting sibling dialogs share one exclusive slot.
|
|
3419
|
+
* @returns the seat; spread `pos ?? MEASURE_STYLE` onto the portaled panel.
|
|
3420
|
+
*/
|
|
3421
|
+
function useStatDialog(controlled) {
|
|
3422
|
+
const [ownOpen, setOwnOpen] = (0, react.useState)(false);
|
|
3423
|
+
const open = controlled?.open ?? ownOpen;
|
|
3424
|
+
const setOpen = controlled?.setOpen ?? setOwnOpen;
|
|
3407
3425
|
const rootRef = (0, react.useRef)(null);
|
|
3408
3426
|
const panelRef = (0, react.useRef)(null);
|
|
3409
3427
|
const pos = (0, _deepseek_ai_dsh_client_ui_primitives.useAnchoredPosition)({
|
|
@@ -3424,7 +3442,7 @@ window.__ModuleLoader__.load({
|
|
|
3424
3442
|
return () => {
|
|
3425
3443
|
document.removeEventListener("keydown", onKeyDown);
|
|
3426
3444
|
};
|
|
3427
|
-
}, [open]);
|
|
3445
|
+
}, [open, setOpen]);
|
|
3428
3446
|
return {
|
|
3429
3447
|
open,
|
|
3430
3448
|
setOpen,
|
|
@@ -3433,6 +3451,51 @@ window.__ModuleLoader__.load({
|
|
|
3433
3451
|
pos
|
|
3434
3452
|
};
|
|
3435
3453
|
}
|
|
3454
|
+
//#endregion
|
|
3455
|
+
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-chat/src/client/chat/TurnUsagePanel.module.css.mjs
|
|
3456
|
+
const css$4 = ".Q51KRG_root{min-width:0;display:inline-flex}.Q51KRG_root+.Q51KRG_root{margin-left:-6px}.Q51KRG_trigger{min-width:0;height:calc(28px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-tertiary);font-size:var(--dsh-content-font-size-secondary,13px);font-variant-numeric:tabular-nums;line-height:calc(24px + var(--dsh-content-font-delta,0px));white-space:nowrap;cursor:pointer;background:0 0;border:none;border-radius:28px;align-items:center;gap:4px;padding:6px 8px;display:inline-flex}.Q51KRG_label{text-overflow:ellipsis;min-width:0;overflow:hidden}.Q51KRG_trigger svg{width:calc(15px + var(--dsh-content-font-delta,0px));height:calc(15px + var(--dsh-content-font-delta,0px));flex:none}.Q51KRG_trigger:hover,.Q51KRG_trigger[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary)}@media (width<=480px){.Q51KRG_trigger{width:calc(28px + var(--dsh-content-font-delta,0px));justify-content:center;padding:6px}.Q51KRG_trigger .Q51KRG_label{display:none}.Q51KRG_root+.Q51KRG_root{margin-left:0}}";
|
|
3457
|
+
const tagId$4 = "@deepseek-ai/dsh-client-ui-chat/TurnUsagePanel.module.css";
|
|
3458
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
|
|
3459
|
+
const tag = document.createElement("style");
|
|
3460
|
+
tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-chat";
|
|
3461
|
+
tag.dataset.pluginCss = tagId$4;
|
|
3462
|
+
tag.textContent = css$4;
|
|
3463
|
+
document.head.appendChild(tag);
|
|
3464
|
+
}
|
|
3465
|
+
var TurnUsagePanel_module_css_default = {
|
|
3466
|
+
"label": "Q51KRG_label",
|
|
3467
|
+
"root": "Q51KRG_root",
|
|
3468
|
+
"trigger": "Q51KRG_trigger"
|
|
3469
|
+
};
|
|
3470
|
+
//#endregion
|
|
3471
|
+
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-chat/src/client/chat/stat-dialog.module.css.mjs
|
|
3472
|
+
const css$3 = ".bRhRbq_panel{z-index:1100;box-sizing:border-box;background:var(--dsw-specific-menu);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);width:max-content;min-width:min(300px,100vw - 24px);max-width:min(440px,100vw - 24px);box-shadow:var(--dsw-elevation-prominent);color:var(--dsw-alias-label-secondary);cursor:default;border:0;border-radius:12px;padding:16px;font-size:12px;line-height:18px;position:fixed}.bRhRbq_title{color:var(--dsw-alias-label-primary);justify-content:space-between;gap:16px;margin-bottom:8px;font-weight:500;display:flex}.bRhRbq_titleRule{border-top:.5px solid var(--dsw-alias-border-l2);margin-bottom:10px}.bRhRbq_titleValue{font-variant-numeric:tabular-nums}.bRhRbq_titleLabel{align-items:center;gap:6px;min-width:0;display:inline-flex}.bRhRbq_titleLabel svg{flex:none;width:14px;height:14px}.bRhRbq_details{color:var(--dsw-alias-label-tertiary);grid-template-columns:minmax(76px,auto) minmax(0,1fr);gap:6px 16px;margin:0;display:grid}.bRhRbq_details dt,.bRhRbq_details dd{min-width:0;margin:0}.bRhRbq_details dd{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;text-align:right}.bRhRbq_details .bRhRbq_route{overflow-wrap:anywhere}.bRhRbq_reasoning{color:var(--dsw-alias-label-tertiary);white-space:nowrap}";
|
|
3473
|
+
const tagId$3 = "@deepseek-ai/dsh-client-ui-chat/stat-dialog.module.css";
|
|
3474
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
3475
|
+
const tag = document.createElement("style");
|
|
3476
|
+
tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-chat";
|
|
3477
|
+
tag.dataset.pluginCss = tagId$3;
|
|
3478
|
+
tag.textContent = css$3;
|
|
3479
|
+
document.head.appendChild(tag);
|
|
3480
|
+
}
|
|
3481
|
+
var stat_dialog_module_css_default = {
|
|
3482
|
+
"details": "bRhRbq_details",
|
|
3483
|
+
"panel": "bRhRbq_panel",
|
|
3484
|
+
"reasoning": "bRhRbq_reasoning",
|
|
3485
|
+
"route": "bRhRbq_route",
|
|
3486
|
+
"title": "bRhRbq_title",
|
|
3487
|
+
"titleLabel": "bRhRbq_titleLabel",
|
|
3488
|
+
"titleRule": "bRhRbq_titleRule",
|
|
3489
|
+
"titleValue": "bRhRbq_titleValue"
|
|
3490
|
+
};
|
|
3491
|
+
//#endregion
|
|
3492
|
+
//#region lib/types/client/chat/TurnUsagePanel.js
|
|
3493
|
+
function formatCompactCount(value, t) {
|
|
3494
|
+
return t("message.turnUsage.count", { count: formatTokens(value, t) });
|
|
3495
|
+
}
|
|
3496
|
+
function formatExactCount(value, t) {
|
|
3497
|
+
return t("message.turnUsage.count", { count: formatExactTokens(value, t) });
|
|
3498
|
+
}
|
|
3436
3499
|
/**
|
|
3437
3500
|
* Turn-usage IconActions pill with a click-open Turn-usage details dialog.
|
|
3438
3501
|
* @param props - Turn usage buckets and locale seat.
|
|
@@ -3460,31 +3523,31 @@ window.__ModuleLoader__.load({
|
|
|
3460
3523
|
})]
|
|
3461
3524
|
}), open && (0, react_dom.createPortal)((0, react_jsx_runtime.jsxs)("div", {
|
|
3462
3525
|
ref: panelRef,
|
|
3463
|
-
className:
|
|
3526
|
+
className: stat_dialog_module_css_default.panel,
|
|
3464
3527
|
role: "dialog",
|
|
3465
3528
|
"aria-label": t("message.turnUsage.title"),
|
|
3466
3529
|
style: pos ?? MEASURE_STYLE,
|
|
3467
3530
|
children: [
|
|
3468
3531
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
3469
|
-
className:
|
|
3532
|
+
className: stat_dialog_module_css_default.title,
|
|
3470
3533
|
children: [(0, react_jsx_runtime.jsxs)("span", {
|
|
3471
|
-
className:
|
|
3534
|
+
className: stat_dialog_module_css_default.titleLabel,
|
|
3472
3535
|
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDatabaseOutline16, {}), t("message.turnUsage.title")]
|
|
3473
3536
|
}), (0, react_jsx_runtime.jsx)("span", {
|
|
3474
|
-
className:
|
|
3537
|
+
className: stat_dialog_module_css_default.titleValue,
|
|
3475
3538
|
children: formatExactCount(usage.totalTokens, t)
|
|
3476
3539
|
})]
|
|
3477
3540
|
}),
|
|
3478
3541
|
(0, react_jsx_runtime.jsx)("div", {
|
|
3479
|
-
className:
|
|
3542
|
+
className: stat_dialog_module_css_default.titleRule,
|
|
3480
3543
|
"aria-hidden": true
|
|
3481
3544
|
}),
|
|
3482
3545
|
(0, react_jsx_runtime.jsxs)("dl", {
|
|
3483
|
-
className:
|
|
3546
|
+
className: stat_dialog_module_css_default.details,
|
|
3484
3547
|
"data-turn-usage-details": true,
|
|
3485
3548
|
children: [
|
|
3486
3549
|
routes !== "" && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("dt", { children: t("message.turnUsage.model") }), (0, react_jsx_runtime.jsx)("dd", {
|
|
3487
|
-
className:
|
|
3550
|
+
className: stat_dialog_module_css_default.route,
|
|
3488
3551
|
children: routes
|
|
3489
3552
|
})] }),
|
|
3490
3553
|
cacheHit !== null && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("dt", { children: t("message.turnUsage.cacheHit") }), (0, react_jsx_runtime.jsx)("dd", { children: `${cacheHit}%` })] }),
|
|
@@ -3494,7 +3557,7 @@ window.__ModuleLoader__.load({
|
|
|
3494
3557
|
usage.cacheWriteTokens !== void 0 && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("dt", { children: t("message.turnUsage.cacheWrite") }), (0, react_jsx_runtime.jsx)("dd", { children: formatExactCount(usage.cacheWriteTokens, t) })] }),
|
|
3495
3558
|
(0, react_jsx_runtime.jsx)("dt", { children: t("message.turnUsage.output") }),
|
|
3496
3559
|
(0, react_jsx_runtime.jsxs)("dd", { children: [formatExactCount(usage.outputTokens, t), usage.reasoningTokens !== void 0 && (0, react_jsx_runtime.jsx)("span", {
|
|
3497
|
-
className:
|
|
3560
|
+
className: stat_dialog_module_css_default.reasoning,
|
|
3498
3561
|
children: t("message.turnUsage.reasoning", { tokens: formatExactCount(usage.reasoningTokens, t) })
|
|
3499
3562
|
})] })
|
|
3500
3563
|
]
|
|
@@ -3527,24 +3590,24 @@ window.__ModuleLoader__.load({
|
|
|
3527
3590
|
})]
|
|
3528
3591
|
}), open && (0, react_dom.createPortal)((0, react_jsx_runtime.jsxs)("div", {
|
|
3529
3592
|
ref: panelRef,
|
|
3530
|
-
className:
|
|
3593
|
+
className: stat_dialog_module_css_default.panel,
|
|
3531
3594
|
role: "dialog",
|
|
3532
3595
|
"aria-label": t("message.turnTime.title"),
|
|
3533
3596
|
style: pos ?? MEASURE_STYLE,
|
|
3534
3597
|
children: [
|
|
3535
3598
|
(0, react_jsx_runtime.jsx)("div", {
|
|
3536
|
-
className:
|
|
3599
|
+
className: stat_dialog_module_css_default.title,
|
|
3537
3600
|
children: (0, react_jsx_runtime.jsxs)("span", {
|
|
3538
|
-
className:
|
|
3601
|
+
className: stat_dialog_module_css_default.titleLabel,
|
|
3539
3602
|
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconClockOutline16, {}), t("message.turnTime.title")]
|
|
3540
3603
|
})
|
|
3541
3604
|
}),
|
|
3542
3605
|
(0, react_jsx_runtime.jsx)("div", {
|
|
3543
|
-
className:
|
|
3606
|
+
className: stat_dialog_module_css_default.titleRule,
|
|
3544
3607
|
"aria-hidden": true
|
|
3545
3608
|
}),
|
|
3546
3609
|
(0, react_jsx_runtime.jsxs)("dl", {
|
|
3547
|
-
className:
|
|
3610
|
+
className: stat_dialog_module_css_default.details,
|
|
3548
3611
|
"data-turn-time-details": true,
|
|
3549
3612
|
children: [
|
|
3550
3613
|
(0, react_jsx_runtime.jsx)("dt", { children: t("message.turnTime.duration") }),
|
|
@@ -3569,13 +3632,13 @@ window.__ModuleLoader__.load({
|
|
|
3569
3632
|
}
|
|
3570
3633
|
//#endregion
|
|
3571
3634
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-chat/src/client/chat/TurnTailNodeView.module.css.mjs
|
|
3572
|
-
const css$
|
|
3573
|
-
const tagId$
|
|
3574
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$
|
|
3635
|
+
const css$2 = ".TS9iAW_root{flex-direction:column;gap:16px;display:flex}.TS9iAW_actions{margin-left:-6px}";
|
|
3636
|
+
const tagId$2 = "@deepseek-ai/dsh-client-ui-chat/TurnTailNodeView.module.css";
|
|
3637
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
|
|
3575
3638
|
const tag = document.createElement("style");
|
|
3576
3639
|
tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-chat";
|
|
3577
|
-
tag.dataset.pluginCss = tagId$
|
|
3578
|
-
tag.textContent = css$
|
|
3640
|
+
tag.dataset.pluginCss = tagId$2;
|
|
3641
|
+
tag.textContent = css$2;
|
|
3579
3642
|
document.head.appendChild(tag);
|
|
3580
3643
|
}
|
|
3581
3644
|
var TurnTailNodeView_module_css_default = {
|
|
@@ -3789,22 +3852,25 @@ window.__ModuleLoader__.load({
|
|
|
3789
3852
|
return metrics;
|
|
3790
3853
|
}
|
|
3791
3854
|
//#endregion
|
|
3792
|
-
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-chat/src/client/chat/
|
|
3793
|
-
const css$
|
|
3794
|
-
const tagId$
|
|
3795
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$
|
|
3855
|
+
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-chat/src/client/chat/StatsPills.module.css.mjs
|
|
3856
|
+
const css$1 = ".bOPqQW_root{max-width:var(--dsh-chat-content-width);box-sizing:border-box;width:100%;padding:4px calc(var(--dsh-composer-side-clearance) + 16px) 0px;font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(20px + var(--dsh-content-font-delta-secondary,0px));justify-content:center;gap:12px;margin:0 auto;display:flex}.bOPqQW_anchor{min-width:0;display:inline-flex}.bOPqQW_pill{box-sizing:border-box;max-width:100%;color:var(--dsw-alias-label-tertiary);font:inherit;font-variant-numeric:tabular-nums;line-height:inherit;white-space:nowrap;background:0 0;border:none;border-radius:24px;align-items:center;gap:6px;padding:1px 8px;display:inline-flex}.bOPqQW_pill svg{flex:none;width:14px;height:14px}button.bOPqQW_pill{cursor:pointer}button.bOPqQW_pill:hover,button.bOPqQW_pill[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary)}.bOPqQW_label{text-overflow:ellipsis;min-width:0;overflow:hidden}.bOPqQW_sep{color:var(--dsw-alias-separator-primary);margin:0 6px}";
|
|
3857
|
+
const tagId$1 = "@deepseek-ai/dsh-client-ui-chat/StatsPills.module.css";
|
|
3858
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
3796
3859
|
const tag = document.createElement("style");
|
|
3797
3860
|
tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-chat";
|
|
3798
|
-
tag.dataset.pluginCss = tagId$
|
|
3799
|
-
tag.textContent = css$
|
|
3861
|
+
tag.dataset.pluginCss = tagId$1;
|
|
3862
|
+
tag.textContent = css$1;
|
|
3800
3863
|
document.head.appendChild(tag);
|
|
3801
3864
|
}
|
|
3802
|
-
var
|
|
3803
|
-
"
|
|
3804
|
-
"
|
|
3865
|
+
var StatsPills_module_css_default = {
|
|
3866
|
+
"anchor": "bOPqQW_anchor",
|
|
3867
|
+
"label": "bOPqQW_label",
|
|
3868
|
+
"pill": "bOPqQW_pill",
|
|
3869
|
+
"root": "bOPqQW_root",
|
|
3870
|
+
"sep": "bOPqQW_sep"
|
|
3805
3871
|
};
|
|
3806
3872
|
//#endregion
|
|
3807
|
-
//#region lib/types/client/chat/
|
|
3873
|
+
//#region lib/types/client/chat/StatsPills.js
|
|
3808
3874
|
/**
|
|
3809
3875
|
* Fold assistant and tool-result nodes into window-scoped display totals —
|
|
3810
3876
|
* the FALLBACK for assemblies without the `sessionStats` projection.
|
|
@@ -3889,75 +3955,172 @@ window.__ModuleLoader__.load({
|
|
|
3889
3955
|
function billedInputTokens(usage) {
|
|
3890
3956
|
return usage.uncachedInputTokens + usage.cacheReadTokens + usage.cacheWriteTokens;
|
|
3891
3957
|
}
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
const
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
(0,
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
delayMs: 500,
|
|
3916
|
-
disabled: !truncated,
|
|
3917
|
-
children: (0, react_jsx_runtime.jsx)("div", {
|
|
3918
|
-
ref: rootRef,
|
|
3919
|
-
className: StatsLine_module_css_default.root,
|
|
3920
|
-
children: groups.map((group, i) => (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [i > 0 && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("span", {
|
|
3921
|
-
className: StatsLine_module_css_default.sep,
|
|
3922
|
-
"aria-hidden": true,
|
|
3923
|
-
children: "|"
|
|
3924
|
-
}), " "] }), (0, react_jsx_runtime.jsx)("span", { children: group })] }, group))
|
|
3958
|
+
function exactCount(value, t) {
|
|
3959
|
+
return t("message.turnUsage.count", { count: formatExactTokens(value, t) });
|
|
3960
|
+
}
|
|
3961
|
+
function TimePill({ stats, t, dialog }) {
|
|
3962
|
+
const { open, setOpen, rootRef, panelRef, pos } = useStatDialog(dialog);
|
|
3963
|
+
const counts = t("stats.counts", {
|
|
3964
|
+
turns: stats.turns,
|
|
3965
|
+
steps: stats.steps
|
|
3966
|
+
});
|
|
3967
|
+
const tps = stats.decodeMs > 0 ? t("message.tokensPerSecond", { tps: formatTokensPerSecond(stats.decodeTokens / (stats.decodeMs / 1e3)) }) : null;
|
|
3968
|
+
const label = (0, react_jsx_runtime.jsxs)("span", {
|
|
3969
|
+
className: StatsPills_module_css_default.label,
|
|
3970
|
+
children: [counts, tps !== null && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("span", {
|
|
3971
|
+
className: StatsPills_module_css_default.sep,
|
|
3972
|
+
"aria-hidden": true,
|
|
3973
|
+
children: "·"
|
|
3974
|
+
}), tps] })]
|
|
3975
|
+
});
|
|
3976
|
+
if (stats.llmMs <= 0 && stats.toolMs <= 0 && stats.ttftSteps <= 0 && stats.decodeMs <= 0) return (0, react_jsx_runtime.jsx)("span", {
|
|
3977
|
+
className: StatsPills_module_css_default.anchor,
|
|
3978
|
+
children: (0, react_jsx_runtime.jsxs)("span", {
|
|
3979
|
+
className: StatsPills_module_css_default.pill,
|
|
3980
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconGaugeOutline16, {}), label]
|
|
3925
3981
|
})
|
|
3926
3982
|
});
|
|
3927
|
-
|
|
3928
|
-
|
|
3983
|
+
return (0, react_jsx_runtime.jsxs)("span", {
|
|
3984
|
+
ref: rootRef,
|
|
3985
|
+
className: StatsPills_module_css_default.anchor,
|
|
3986
|
+
children: [(0, react_jsx_runtime.jsxs)("button", {
|
|
3987
|
+
type: "button",
|
|
3988
|
+
className: StatsPills_module_css_default.pill,
|
|
3989
|
+
"aria-haspopup": "dialog",
|
|
3990
|
+
"aria-expanded": open,
|
|
3991
|
+
"aria-label": tps === null ? counts : `${counts} · ${tps}`,
|
|
3992
|
+
onClick: () => {
|
|
3993
|
+
setOpen(!open);
|
|
3994
|
+
},
|
|
3995
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconGaugeOutline16, {}), label]
|
|
3996
|
+
}), open && (0, react_dom.createPortal)((0, react_jsx_runtime.jsxs)("div", {
|
|
3997
|
+
ref: panelRef,
|
|
3998
|
+
className: stat_dialog_module_css_default.panel,
|
|
3999
|
+
role: "dialog",
|
|
4000
|
+
"aria-label": t("stats.dialog.title"),
|
|
4001
|
+
style: pos ?? MEASURE_STYLE,
|
|
4002
|
+
children: [
|
|
4003
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
4004
|
+
className: stat_dialog_module_css_default.title,
|
|
4005
|
+
children: (0, react_jsx_runtime.jsxs)("span", {
|
|
4006
|
+
className: stat_dialog_module_css_default.titleLabel,
|
|
4007
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconGaugeOutline16, {}), t("stats.dialog.title")]
|
|
4008
|
+
})
|
|
4009
|
+
}),
|
|
4010
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
4011
|
+
className: stat_dialog_module_css_default.titleRule,
|
|
4012
|
+
"aria-hidden": true
|
|
4013
|
+
}),
|
|
4014
|
+
(0, react_jsx_runtime.jsxs)("dl", {
|
|
4015
|
+
className: stat_dialog_module_css_default.details,
|
|
4016
|
+
"data-session-stats-details": true,
|
|
4017
|
+
children: [
|
|
4018
|
+
stats.llmMs > 0 && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("dt", { children: t("stats.dialog.llmTime") }), (0, react_jsx_runtime.jsx)("dd", { children: formatDuration(stats.llmMs, t) })] }),
|
|
4019
|
+
stats.toolMs > 0 && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("dt", { children: t("stats.dialog.toolTime") }), (0, react_jsx_runtime.jsx)("dd", { children: formatDuration(stats.toolMs, t) })] }),
|
|
4020
|
+
stats.ttftSteps > 0 && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("dt", { children: t("stats.dialog.ttft") }), (0, react_jsx_runtime.jsx)("dd", { children: formatDuration(stats.ttftMs / stats.ttftSteps, t) })] }),
|
|
4021
|
+
stats.decodeMs > 0 && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("dt", { children: t("stats.dialog.speed") }), (0, react_jsx_runtime.jsx)("dd", { children: t("message.tokensPerSecond", { tps: formatTokensPerSecond(stats.decodeTokens / (stats.decodeMs / 1e3)) }) })] })
|
|
4022
|
+
]
|
|
4023
|
+
})
|
|
4024
|
+
]
|
|
4025
|
+
}), document.body)]
|
|
4026
|
+
});
|
|
4027
|
+
}
|
|
4028
|
+
function UsagePill({ usage, t, dialog }) {
|
|
4029
|
+
const { open, setOpen, rootRef, panelRef, pos } = useStatDialog(dialog);
|
|
4030
|
+
const total = billedInputTokens(usage) + usage.outputTokens;
|
|
4031
|
+
const totalText = t("message.turnUsage.count", { count: formatTokens(total, t) });
|
|
4032
|
+
const cacheHit = cacheHitPercent(usage);
|
|
4033
|
+
const cacheHitText = cacheHit !== null ? t("stats.cacheHit", { percent: cacheHit }) : null;
|
|
4034
|
+
return (0, react_jsx_runtime.jsxs)("span", {
|
|
4035
|
+
ref: rootRef,
|
|
4036
|
+
className: StatsPills_module_css_default.anchor,
|
|
4037
|
+
children: [(0, react_jsx_runtime.jsxs)("button", {
|
|
4038
|
+
type: "button",
|
|
4039
|
+
className: StatsPills_module_css_default.pill,
|
|
4040
|
+
"aria-haspopup": "dialog",
|
|
4041
|
+
"aria-expanded": open,
|
|
4042
|
+
"aria-label": cacheHitText === null ? totalText : `${totalText} · ${cacheHitText}`,
|
|
4043
|
+
onClick: () => {
|
|
4044
|
+
setOpen(!open);
|
|
4045
|
+
},
|
|
4046
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDatabaseOutline16, {}), (0, react_jsx_runtime.jsxs)("span", {
|
|
4047
|
+
className: StatsPills_module_css_default.label,
|
|
4048
|
+
children: [totalText, cacheHitText !== null && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("span", {
|
|
4049
|
+
className: StatsPills_module_css_default.sep,
|
|
4050
|
+
"aria-hidden": true,
|
|
4051
|
+
children: "·"
|
|
4052
|
+
}), cacheHitText] })]
|
|
4053
|
+
})]
|
|
4054
|
+
}), open && (0, react_dom.createPortal)((0, react_jsx_runtime.jsxs)("div", {
|
|
4055
|
+
ref: panelRef,
|
|
4056
|
+
className: stat_dialog_module_css_default.panel,
|
|
4057
|
+
role: "dialog",
|
|
4058
|
+
"aria-label": t("stats.dialog.usageTitle"),
|
|
4059
|
+
style: pos ?? MEASURE_STYLE,
|
|
4060
|
+
children: [
|
|
4061
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
4062
|
+
className: stat_dialog_module_css_default.title,
|
|
4063
|
+
children: [(0, react_jsx_runtime.jsxs)("span", {
|
|
4064
|
+
className: stat_dialog_module_css_default.titleLabel,
|
|
4065
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDatabaseOutline16, {}), t("stats.dialog.usageTitle")]
|
|
4066
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
4067
|
+
className: stat_dialog_module_css_default.titleValue,
|
|
4068
|
+
children: exactCount(total, t)
|
|
4069
|
+
})]
|
|
4070
|
+
}),
|
|
4071
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
4072
|
+
className: stat_dialog_module_css_default.titleRule,
|
|
4073
|
+
"aria-hidden": true
|
|
4074
|
+
}),
|
|
4075
|
+
(0, react_jsx_runtime.jsxs)("dl", {
|
|
4076
|
+
className: stat_dialog_module_css_default.details,
|
|
4077
|
+
"data-session-stats-usage": true,
|
|
4078
|
+
children: [
|
|
4079
|
+
cacheHit !== null && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("dt", { children: t("message.turnUsage.cacheHit") }), (0, react_jsx_runtime.jsx)("dd", { children: `${cacheHit}%` })] }),
|
|
4080
|
+
(0, react_jsx_runtime.jsx)("dt", { children: t("message.turnUsage.input") }),
|
|
4081
|
+
(0, react_jsx_runtime.jsx)("dd", { children: exactCount(usage.uncachedInputTokens, t) }),
|
|
4082
|
+
(0, react_jsx_runtime.jsx)("dt", { children: t("message.turnUsage.cacheRead") }),
|
|
4083
|
+
(0, react_jsx_runtime.jsx)("dd", { children: exactCount(usage.cacheReadTokens, t) }),
|
|
4084
|
+
(0, react_jsx_runtime.jsx)("dt", { children: t("message.turnUsage.cacheWrite") }),
|
|
4085
|
+
(0, react_jsx_runtime.jsx)("dd", { children: exactCount(usage.cacheWriteTokens, t) }),
|
|
4086
|
+
(0, react_jsx_runtime.jsx)("dt", { children: t("message.turnUsage.output") }),
|
|
4087
|
+
(0, react_jsx_runtime.jsx)("dd", { children: exactCount(usage.outputTokens, t) })
|
|
4088
|
+
]
|
|
4089
|
+
})
|
|
4090
|
+
]
|
|
4091
|
+
}), document.body)]
|
|
4092
|
+
});
|
|
4093
|
+
}
|
|
4094
|
+
const StatsPills = (0, react.memo)(function StatsPills({ useChat, useProjection, t }) {
|
|
3929
4095
|
const settledNodes = useChat((s) => s.legacy.nodes);
|
|
3930
4096
|
const usage = useProjection("tokenUsage");
|
|
4097
|
+
const [openPill, setOpenPill] = (0, react.useState)(null);
|
|
3931
4098
|
const projected = useProjection("sessionStats");
|
|
3932
4099
|
const stats = (0, react.useMemo)(() => projected ?? deriveStats(settledNodes), [projected, settledNodes]);
|
|
3933
|
-
const
|
|
3934
|
-
if (stats.steps
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
if (groups.length === 0) return null;
|
|
3958
|
-
return (0, react_jsx_runtime.jsx)(StatsLineContent, {
|
|
3959
|
-
groups,
|
|
3960
|
-
line
|
|
4100
|
+
const hasTokens = usage !== void 0 && (billedInputTokens(usage) > 0 || usage.outputTokens > 0);
|
|
4101
|
+
if (stats.steps === 0 && !hasTokens) return null;
|
|
4102
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
4103
|
+
className: StatsPills_module_css_default.root,
|
|
4104
|
+
"data-composer-stats": true,
|
|
4105
|
+
children: [stats.steps > 0 && (0, react_jsx_runtime.jsx)(TimePill, {
|
|
4106
|
+
stats,
|
|
4107
|
+
t,
|
|
4108
|
+
dialog: {
|
|
4109
|
+
open: openPill === "time",
|
|
4110
|
+
setOpen: (open) => {
|
|
4111
|
+
setOpenPill(open ? "time" : null);
|
|
4112
|
+
}
|
|
4113
|
+
}
|
|
4114
|
+
}), hasTokens && (0, react_jsx_runtime.jsx)(UsagePill, {
|
|
4115
|
+
usage,
|
|
4116
|
+
t,
|
|
4117
|
+
dialog: {
|
|
4118
|
+
open: openPill === "usage",
|
|
4119
|
+
setOpen: (open) => {
|
|
4120
|
+
setOpenPill(open ? "usage" : null);
|
|
4121
|
+
}
|
|
4122
|
+
}
|
|
4123
|
+
})]
|
|
3961
4124
|
});
|
|
3962
4125
|
});
|
|
3963
4126
|
//#endregion
|
|
@@ -5314,7 +5477,7 @@ window.__ModuleLoader__.load({
|
|
|
5314
5477
|
function sameContribution(left, right) {
|
|
5315
5478
|
return left !== void 0 && left.anchorSeq === right.anchorSeq && left.partial?.blocks === right.partial?.blocks && left.partial?.turn === right.partial?.turn && left.partial?.step === right.partial?.step && left.running === right.running && sameReferences$1(left.nodes, right.nodes);
|
|
5316
5479
|
}
|
|
5317
|
-
/** Incremental compatibility projection for
|
|
5480
|
+
/** Incremental compatibility projection for StatsPills and legacy top-level snapshot fields. */
|
|
5318
5481
|
var LegacySliceBuilder = class {
|
|
5319
5482
|
contributions = /* @__PURE__ */ new Map();
|
|
5320
5483
|
finalizedContributions = /* @__PURE__ */ new Map();
|
|
@@ -5521,6 +5684,7 @@ window.__ModuleLoader__.load({
|
|
|
5521
5684
|
//#region ../../core/session/src/surface.ts
|
|
5522
5685
|
/** Runtime counterpart of the message-producing event union. */
|
|
5523
5686
|
const SURFACE_EVENT_TYPES = new Set([
|
|
5687
|
+
"system/message",
|
|
5524
5688
|
"user/message",
|
|
5525
5689
|
"assistant/message",
|
|
5526
5690
|
"tool/result"
|
|
@@ -5945,7 +6109,7 @@ window.__ModuleLoader__.load({
|
|
|
5945
6109
|
}
|
|
5946
6110
|
//#endregion
|
|
5947
6111
|
//#region lib/types/client/conversation-nodes/request-prompt.js
|
|
5948
|
-
/** Place a request's system
|
|
6112
|
+
/** Place a request's system prompt at the start of its visible message series. */
|
|
5949
6113
|
function requestPromptAnchor(match, previous, isInitial) {
|
|
5950
6114
|
if (match.location.kind !== "step") return match.event.seq;
|
|
5951
6115
|
if (previous === void 0 && !isInitial) return match.event.seq;
|
|
@@ -5958,7 +6122,41 @@ window.__ModuleLoader__.load({
|
|
|
5958
6122
|
return current?.kind === "system-prompt" ? current.anchorSeq : requestPromptAnchor(match, previous, isInitial);
|
|
5959
6123
|
}
|
|
5960
6124
|
/**
|
|
5961
|
-
*
|
|
6125
|
+
* System-prompt surface node Definition for the Chat target. It owns every
|
|
6126
|
+
* `system/message` event on the Chat target so the unknown-surface fallback
|
|
6127
|
+
* never renders the prompt as a transcript row. Each nonempty append owns a
|
|
6128
|
+
* prompt card, even without a loaded request header. Initial cards precede
|
|
6129
|
+
* their step's input; in-history updates stay at their own positions. The
|
|
6130
|
+
* request-prompt Definition owns replacement and later-series cards. Positional
|
|
6131
|
+
* replacements advance the effective prompt without changing historical cards.
|
|
6132
|
+
* @param inspect - Pure surface interpretation supplied by uiConversation.
|
|
6133
|
+
* @returns The Chat system-prompt Definition.
|
|
6134
|
+
*/
|
|
6135
|
+
function systemMessageDefinition(inspect) {
|
|
6136
|
+
return {
|
|
6137
|
+
kind: "system-message",
|
|
6138
|
+
target: "chat",
|
|
6139
|
+
match: (event) => event.type === "system/message" || "surfaceOp" in event && event.surfaceOp !== "append" ? {
|
|
6140
|
+
id: String(event.seq),
|
|
6141
|
+
role: "start"
|
|
6142
|
+
} : null,
|
|
6143
|
+
start: (_context, match, reader) => {
|
|
6144
|
+
return inspect(reader.previous("system-message")?.state, match.event);
|
|
6145
|
+
},
|
|
6146
|
+
update: (context) => context.state,
|
|
6147
|
+
buildViewNode: (context) => {
|
|
6148
|
+
const state = context.state?.introduced;
|
|
6149
|
+
if (state === void 0 || state.text === "" || context.start?.event.type !== "system/message" || context.start.event.surfaceOp !== "append") return null;
|
|
6150
|
+
return chatNode(context, "system-prompt", state.update ? state.seq : requestPromptAnchor(context.start, void 0, true), {
|
|
6151
|
+
text: state.text,
|
|
6152
|
+
...state.update ? { update: true } : {}
|
|
6153
|
+
});
|
|
6154
|
+
}
|
|
6155
|
+
};
|
|
6156
|
+
}
|
|
6157
|
+
/**
|
|
6158
|
+
* Request-header prompt Definition for the Chat target. Resume and explicit
|
|
6159
|
+
* series starts retain a prompt card even when the system text is unchanged.
|
|
5962
6160
|
* @param inspect - the shared prompt interpretation, supplied by the
|
|
5963
6161
|
* uiConversation service (a client bundle cannot value-import it).
|
|
5964
6162
|
* @returns the Chat request-prompt Definition.
|
|
@@ -5974,15 +6172,19 @@ window.__ModuleLoader__.load({
|
|
|
5974
6172
|
start: (context, match, reader) => {
|
|
5975
6173
|
if (match.event.type !== "request/header") throw new Error("request-prompt start requires request/header");
|
|
5976
6174
|
const previous = reader.previous("request-prompt")?.state;
|
|
6175
|
+
const systemContext = reader.previous("system-message");
|
|
6176
|
+
const system = systemContext?.state.effective;
|
|
5977
6177
|
const location = match.location.kind === "step" ? {
|
|
5978
6178
|
turn: match.location.turn.turn,
|
|
5979
6179
|
step: match.location.step.step
|
|
5980
6180
|
} : {};
|
|
5981
|
-
const inspection = inspect(previous?.prompt, match.event);
|
|
6181
|
+
const inspection = inspect(previous?.prompt, match.event, system);
|
|
5982
6182
|
const change = inspection.change?.kind;
|
|
6183
|
+
const systemEvent = systemContext?.matches[0]?.event;
|
|
6184
|
+
const shownByUpdate = system !== void 0 && systemEvent?.type === "system/message" && systemEvent.surfaceOp === "append" && (system.update || previous === void 0) && system.turn === location.turn && system.step === location.step;
|
|
5983
6185
|
return {
|
|
5984
6186
|
anchorSeq: stableRequestPromptAnchor(context, match, previous, match.event.data.reason === "initial"),
|
|
5985
|
-
showsPrompt: previous === void 0 || match.event.data.reason
|
|
6187
|
+
showsPrompt: !shownByUpdate && (previous === void 0 || match.event.data.reason !== "change" || match.event.data.startsSeries === true || change === "system" || change === "system-and-tools"),
|
|
5986
6188
|
...location,
|
|
5987
6189
|
...inspection
|
|
5988
6190
|
};
|
|
@@ -5999,11 +6201,12 @@ window.__ModuleLoader__.load({
|
|
|
5999
6201
|
};
|
|
6000
6202
|
}
|
|
6001
6203
|
/**
|
|
6002
|
-
* Register model-request
|
|
6204
|
+
* Register the system-prompt surface node and the model-request prompt card in the Chat flow.
|
|
6003
6205
|
* @param ctx - Owning UI Conversation context.
|
|
6004
6206
|
*/
|
|
6005
6207
|
function registerRequestPromptConversationNode(ctx) {
|
|
6006
|
-
ctx.uiConversation.events.register(
|
|
6208
|
+
ctx.uiConversation.events.register(systemMessageDefinition((previous, event) => ctx.uiConversation.inspectSystemPrompt(previous, event)));
|
|
6209
|
+
ctx.uiConversation.events.register(requestPromptDefinition((previous, event, system) => ctx.uiConversation.inspectRequestPrompt(previous, event, system)));
|
|
6007
6210
|
}
|
|
6008
6211
|
//#endregion
|
|
6009
6212
|
//#region lib/types/client/conversation-nodes/retry.js
|
|
@@ -6198,13 +6401,13 @@ window.__ModuleLoader__.load({
|
|
|
6198
6401
|
}
|
|
6199
6402
|
function updateDispatch(state, match) {
|
|
6200
6403
|
const event = match.event;
|
|
6201
|
-
if (event.type !== "tool/
|
|
6404
|
+
if (event.type !== "tool/ptc-dispatch-start" && event.type !== "tool/ptc-dispatch") return state;
|
|
6202
6405
|
const data = event.data;
|
|
6203
6406
|
const parentCallId = String(data.parentCallId);
|
|
6204
6407
|
const subCallId = String(data.subCallId);
|
|
6205
6408
|
const siblings = state.children.get(parentCallId) ?? [];
|
|
6206
6409
|
const index = siblings.findIndex((candidate) => candidate.callId === subCallId);
|
|
6207
|
-
if (event.type === "tool/
|
|
6410
|
+
if (event.type === "tool/ptc-dispatch-start") {
|
|
6208
6411
|
if (index >= 0 || !acceptsEdge(state, parentCallId, subCallId)) return state;
|
|
6209
6412
|
const children = new Map(state.children);
|
|
6210
6413
|
children.set(parentCallId, [...siblings, childCall(match, data)]);
|
|
@@ -6290,7 +6493,7 @@ window.__ModuleLoader__.load({
|
|
|
6290
6493
|
for (const candidate of context.matches) state = updateDispatch(state, candidate);
|
|
6291
6494
|
return state;
|
|
6292
6495
|
}
|
|
6293
|
-
/** Root Tool lifecycle and nested
|
|
6496
|
+
/** Root Tool lifecycle and nested PTC dispatch Definition. */
|
|
6294
6497
|
const toolDefinition = {
|
|
6295
6498
|
kind: "tool-call",
|
|
6296
6499
|
target: "chat",
|
|
@@ -6303,7 +6506,7 @@ window.__ModuleLoader__.load({
|
|
|
6303
6506
|
id: String(event.data.message.source.callId),
|
|
6304
6507
|
role: "update"
|
|
6305
6508
|
};
|
|
6306
|
-
if (event.type === "tool/
|
|
6509
|
+
if (event.type === "tool/ptc-dispatch-start" || event.type === "tool/ptc-dispatch") {
|
|
6307
6510
|
const rootCallId = event.data.rootCallId;
|
|
6308
6511
|
return typeof rootCallId === "string" && rootCallId !== "" ? {
|
|
6309
6512
|
id: rootCallId,
|
|
@@ -7102,160 +7305,6 @@ window.__ModuleLoader__.load({
|
|
|
7102
7305
|
registerChatConversationView(ctx);
|
|
7103
7306
|
}
|
|
7104
7307
|
//#endregion
|
|
7105
|
-
//#region lib/types/client/details/tool-node-reader.js
|
|
7106
|
-
function toolNode(node) {
|
|
7107
|
-
return node?.kind === "tool-call" ? node : void 0;
|
|
7108
|
-
}
|
|
7109
|
-
/**
|
|
7110
|
-
* Find any root or nested Tool lifecycle through the internal Node store.
|
|
7111
|
-
* @param snapshot - current Conversation snapshot.
|
|
7112
|
-
* @param callId - root or nested call identity.
|
|
7113
|
-
* @returns current Tool lifecycle when materialized in the loaded window.
|
|
7114
|
-
*/
|
|
7115
|
-
function findToolCall(snapshot, callId) {
|
|
7116
|
-
const visit = (block) => {
|
|
7117
|
-
if (block.callId === callId) return block;
|
|
7118
|
-
for (const child of block.subCalls) {
|
|
7119
|
-
const found = visit(child);
|
|
7120
|
-
if (found !== void 0) return found;
|
|
7121
|
-
}
|
|
7122
|
-
};
|
|
7123
|
-
for (const node of snapshot.nodes.values()) {
|
|
7124
|
-
const root = toolNode(node)?.data.root;
|
|
7125
|
-
if (root === void 0) continue;
|
|
7126
|
-
const found = visit(root);
|
|
7127
|
-
if (found !== void 0) return found;
|
|
7128
|
-
}
|
|
7129
|
-
}
|
|
7130
|
-
//#endregion
|
|
7131
|
-
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-chat/src/client/details/DetailsPanel.module.css.mjs
|
|
7132
|
-
const css$1 = "._2ctAZa_root{border-left:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);flex-direction:column;min-width:0;height:100%;display:flex}._2ctAZa_header{border-bottom:.5px solid var(--dsw-alias-border-l2);justify-content:space-between;align-items:center;gap:8px;padding:14px 12px 12px;display:flex}._2ctAZa_title{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:500;line-height:20px;overflow:hidden}._2ctAZa_close{corner-shape:round;width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:999px;flex:none;place-items:center;display:grid}._2ctAZa_close:hover{background:var(--dsw-alias-interactive-bg-hover)}._2ctAZa_body{flex:1;min-height:0;padding:12px 16px;overflow-y:auto}._2ctAZa_empty{color:var(--dsw-alias-label-tertiary);padding:8px 0;font-size:13px;line-height:20px}._2ctAZa_section{margin-bottom:16px}._2ctAZa_sectionLabel{color:var(--dsw-alias-label-secondary);margin-bottom:6px;font-size:12px;font-weight:500;line-height:18px}._2ctAZa_code{background:var(--dsw-alias-markdown-code-block);font-family:var(--ds-font-family-code);color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;border-radius:12px;margin:0;padding:16px;font-size:13px;line-height:22px}._2ctAZa_code[data-error]{color:var(--dsw-alias-state-error-primary)}";
|
|
7133
|
-
const tagId$1 = "@deepseek-ai/dsh-client-ui-chat/DetailsPanel.module.css";
|
|
7134
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
7135
|
-
const tag = document.createElement("style");
|
|
7136
|
-
tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-chat";
|
|
7137
|
-
tag.dataset.pluginCss = tagId$1;
|
|
7138
|
-
tag.textContent = css$1;
|
|
7139
|
-
document.head.appendChild(tag);
|
|
7140
|
-
}
|
|
7141
|
-
var DetailsPanel_module_css_default = {
|
|
7142
|
-
"body": "_2ctAZa_body",
|
|
7143
|
-
"close": "_2ctAZa_close",
|
|
7144
|
-
"code": "_2ctAZa_code",
|
|
7145
|
-
"empty": "_2ctAZa_empty",
|
|
7146
|
-
"header": "_2ctAZa_header",
|
|
7147
|
-
"root": "_2ctAZa_root",
|
|
7148
|
-
"section": "_2ctAZa_section",
|
|
7149
|
-
"sectionLabel": "_2ctAZa_sectionLabel",
|
|
7150
|
-
"title": "_2ctAZa_title"
|
|
7151
|
-
};
|
|
7152
|
-
//#endregion
|
|
7153
|
-
//#region lib/types/client/details/DetailsPanel.js
|
|
7154
|
-
function settledMaterial(node, callId) {
|
|
7155
|
-
return {
|
|
7156
|
-
name: node.call?.name ?? callId,
|
|
7157
|
-
argsRaw: node.call?.argsRaw ?? null,
|
|
7158
|
-
block: node
|
|
7159
|
-
};
|
|
7160
|
-
}
|
|
7161
|
-
function runningMaterial(call) {
|
|
7162
|
-
return {
|
|
7163
|
-
name: call.name,
|
|
7164
|
-
argsRaw: call.argsRaw,
|
|
7165
|
-
block: call
|
|
7166
|
-
};
|
|
7167
|
-
}
|
|
7168
|
-
function materialFor(s, callId) {
|
|
7169
|
-
const found = findToolCall(s, callId);
|
|
7170
|
-
if (found === void 0) return null;
|
|
7171
|
-
return "kind" in found ? settledMaterial(found, callId) : runningMaterial(found);
|
|
7172
|
-
}
|
|
7173
|
-
function pretty(raw) {
|
|
7174
|
-
try {
|
|
7175
|
-
return JSON.stringify(JSON.parse(raw), null, 2);
|
|
7176
|
-
} catch {
|
|
7177
|
-
return raw;
|
|
7178
|
-
}
|
|
7179
|
-
}
|
|
7180
|
-
/** Flatten a settled result for the no-ui-tool fallback. */
|
|
7181
|
-
function rawResultText(block) {
|
|
7182
|
-
if (!("kind" in block)) return "";
|
|
7183
|
-
const parts = block.content.map((item) => item.type === "text" ? item.text : JSON.stringify(item, null, 2));
|
|
7184
|
-
if (parts.length === 0 && block.error !== void 0) parts.push(`${block.error.name}: ${block.error.code}`);
|
|
7185
|
-
return parts.join("\n");
|
|
7186
|
-
}
|
|
7187
|
-
function DetailsPanel({ useChat, useSessions, sessionId, useStore, renderSlot, closeDetails, t }) {
|
|
7188
|
-
const selection = useStore((s) => s.selection);
|
|
7189
|
-
const sessionCwd = useSessions((list) => list.byId[sessionId]?.cwd);
|
|
7190
|
-
const callId = selection?.callId;
|
|
7191
|
-
const material = useChat((s) => callId === void 0 ? null : materialFor(s, callId), (a, b) => (0, _deepseek_ai_dsh_client_store.shallowEqual)(a, b));
|
|
7192
|
-
return (0, react_jsx_runtime.jsxs)("div", {
|
|
7193
|
-
className: DetailsPanel_module_css_default.root,
|
|
7194
|
-
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
7195
|
-
className: DetailsPanel_module_css_default.header,
|
|
7196
|
-
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
7197
|
-
className: DetailsPanel_module_css_default.title,
|
|
7198
|
-
children: selection === null ? t("details.title") : material?.name ?? selection.toolName ?? t("details.title")
|
|
7199
|
-
}), (0, react_jsx_runtime.jsx)("button", {
|
|
7200
|
-
type: "button",
|
|
7201
|
-
className: DetailsPanel_module_css_default.close,
|
|
7202
|
-
"aria-label": t("details.close"),
|
|
7203
|
-
onClick: () => {
|
|
7204
|
-
closeDetails();
|
|
7205
|
-
},
|
|
7206
|
-
children: (0, react_jsx_runtime.jsx)("svg", {
|
|
7207
|
-
viewBox: "0 0 16 16",
|
|
7208
|
-
width: "14",
|
|
7209
|
-
height: "14",
|
|
7210
|
-
"aria-hidden": true,
|
|
7211
|
-
children: (0, react_jsx_runtime.jsx)("path", {
|
|
7212
|
-
d: "M4 4l8 8M12 4l-8 8",
|
|
7213
|
-
stroke: "currentColor",
|
|
7214
|
-
strokeWidth: "1.5",
|
|
7215
|
-
strokeLinecap: "round"
|
|
7216
|
-
})
|
|
7217
|
-
})
|
|
7218
|
-
})]
|
|
7219
|
-
}), (0, react_jsx_runtime.jsx)("div", {
|
|
7220
|
-
className: DetailsPanel_module_css_default.body,
|
|
7221
|
-
children: selection === null || callId === void 0 ? (0, react_jsx_runtime.jsx)("div", {
|
|
7222
|
-
className: DetailsPanel_module_css_default.empty,
|
|
7223
|
-
children: t("details.empty")
|
|
7224
|
-
}) : material === null ? (0, react_jsx_runtime.jsx)("div", {
|
|
7225
|
-
className: DetailsPanel_module_css_default.empty,
|
|
7226
|
-
children: t("details.notInWindow")
|
|
7227
|
-
}) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [material.argsRaw !== null && (0, react_jsx_runtime.jsxs)("section", {
|
|
7228
|
-
className: DetailsPanel_module_css_default.section,
|
|
7229
|
-
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
7230
|
-
className: DetailsPanel_module_css_default.sectionLabel,
|
|
7231
|
-
children: t("details.input")
|
|
7232
|
-
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.CodeBlock, {
|
|
7233
|
-
code: pretty(material.argsRaw),
|
|
7234
|
-
lang: "json",
|
|
7235
|
-
copyLabel: t("copy"),
|
|
7236
|
-
copiedLabel: t("copied")
|
|
7237
|
-
})]
|
|
7238
|
-
}), (0, react_jsx_runtime.jsxs)("section", {
|
|
7239
|
-
className: DetailsPanel_module_css_default.section,
|
|
7240
|
-
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
7241
|
-
className: DetailsPanel_module_css_default.sectionLabel,
|
|
7242
|
-
children: t("details.output")
|
|
7243
|
-
}), (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderSlot("conversation.details.tool", {
|
|
7244
|
-
block: material.block,
|
|
7245
|
-
cwd: sessionCwd
|
|
7246
|
-
}, { fallback: "kind" in material.block ? (0, react_jsx_runtime.jsx)("pre", {
|
|
7247
|
-
className: DetailsPanel_module_css_default.code,
|
|
7248
|
-
"data-error": material.block.isError || void 0,
|
|
7249
|
-
children: rawResultText(material.block)
|
|
7250
|
-
}) : (0, react_jsx_runtime.jsx)("div", {
|
|
7251
|
-
className: DetailsPanel_module_css_default.empty,
|
|
7252
|
-
children: t("details.running")
|
|
7253
|
-
}) }) }, callId)]
|
|
7254
|
-
})] })
|
|
7255
|
-
})]
|
|
7256
|
-
});
|
|
7257
|
-
}
|
|
7258
|
-
//#endregion
|
|
7259
7308
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-chat/src/client/settings/TranscriptViewRow.module.css.mjs
|
|
7260
7309
|
const css = ".lats3W_row{border-bottom:.5px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:16px 0;display:flex}.lats3W_rowText{flex-direction:column;flex:1;gap:4px;min-width:0;padding-right:48px;display:flex}.lats3W_title{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:400;line-height:22px}.lats3W_desc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px}.lats3W_selector{background:var(--dsw-alias-bg-module-platform);height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:12px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.lats3W_selector:hover{background:var(--dsw-alias-interactive-bg-hover)}.lats3W_chevron{flex:none}";
|
|
7261
7310
|
const tagId = "@deepseek-ai/dsh-client-ui-chat/TranscriptViewRow.module.css";
|
|
@@ -8201,11 +8250,11 @@ window.__ModuleLoader__.load({
|
|
|
8201
8250
|
"sessions",
|
|
8202
8251
|
"uiSession",
|
|
8203
8252
|
"uiConversation",
|
|
8204
|
-
"layout",
|
|
8205
8253
|
"locale",
|
|
8206
8254
|
"settingsScope",
|
|
8207
8255
|
"remote",
|
|
8208
|
-
"remote.session"
|
|
8256
|
+
"remote.session",
|
|
8257
|
+
"sidebarRight"
|
|
8209
8258
|
];
|
|
8210
8259
|
/**
|
|
8211
8260
|
* Mount all Chat-owned contributions.
|
|
@@ -8270,7 +8319,7 @@ window.__ModuleLoader__.load({
|
|
|
8270
8319
|
}
|
|
8271
8320
|
},
|
|
8272
8321
|
store: chatStore,
|
|
8273
|
-
inject: (sessionId
|
|
8322
|
+
inject: (sessionId) => {
|
|
8274
8323
|
const binding = ctx.sessions.binding(sessionId);
|
|
8275
8324
|
if (binding === void 0) throw new Error(`ui-chat: unknown session "${sessionId}"`);
|
|
8276
8325
|
const session = binding.session;
|
|
@@ -8281,15 +8330,13 @@ window.__ModuleLoader__.load({
|
|
|
8281
8330
|
chatNode: (key) => chat.getSnapshot().nodes.source(key),
|
|
8282
8331
|
chatNodeProcess: (key) => chat.getSnapshot().nodes.processSource(key)
|
|
8283
8332
|
},
|
|
8284
|
-
openDetails: (target) => {
|
|
8285
|
-
actions.select(target);
|
|
8286
|
-
ctx.layout.openDetails();
|
|
8287
|
-
},
|
|
8288
8333
|
fileMentions: (owner) => ctx.get("chatFileMentions")?.forClosing(owner),
|
|
8289
|
-
openFile: async (path) => {
|
|
8334
|
+
openFile: async (path, options) => {
|
|
8290
8335
|
const cwd = ctx.sessions.list.getSnapshot().byId[sessionId]?.cwd;
|
|
8291
|
-
const
|
|
8292
|
-
if (
|
|
8336
|
+
const url = fileAddressFor(sessionId, cwd, path);
|
|
8337
|
+
if (options?.line === void 0) ctx.sidebarRight.openResource(url);
|
|
8338
|
+
else ctx.sidebarRight.openResource(url, { params: { line: options.line } });
|
|
8339
|
+
await Promise.resolve();
|
|
8293
8340
|
},
|
|
8294
8341
|
loadOlder: () => {
|
|
8295
8342
|
session.loadOlder();
|
|
@@ -8321,20 +8368,8 @@ window.__ModuleLoader__.load({
|
|
|
8321
8368
|
id: "stats",
|
|
8322
8369
|
order: 0,
|
|
8323
8370
|
locale: NS
|
|
8324
|
-
},
|
|
8371
|
+
}, StatsPills));
|
|
8325
8372
|
ctx.slots.inject("conversation.approval.detail", () => ctx.slots.register({ name: "conversation.approval.detail" }, ApprovalCommand));
|
|
8326
|
-
ctx.slots.inject("details", () => ctx.slots.register({
|
|
8327
|
-
name: "details",
|
|
8328
|
-
locale: NS,
|
|
8329
|
-
children: { "conversation.details.tool": {
|
|
8330
|
-
kind: "single",
|
|
8331
|
-
scope: "session"
|
|
8332
|
-
} },
|
|
8333
|
-
store: chatStore,
|
|
8334
|
-
inject: () => ({ closeDetails: () => {
|
|
8335
|
-
ctx.layout.closeDetails();
|
|
8336
|
-
} })
|
|
8337
|
-
}, DetailsPanel));
|
|
8338
8373
|
}
|
|
8339
8374
|
//#endregion
|
|
8340
8375
|
exports.EMPTY_CHAT_SNAPSHOT = EMPTY_CHAT_SNAPSHOT;
|