dsh-sidenote 0.3.1 → 0.3.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/lib/client.js +724 -95
- package/lib/types/client/chat/cards.d.ts +4 -0
- package/lib/types/client/locales.d.ts +10 -0
- package/lib/types/client/sidechat/PendingCard.d.ts +4 -0
- package/lib/types/client/sidechat/notify.d.ts +16 -0
- package/lib/types/client/sidechat/pending.d.ts +71 -0
- package/package.json +1 -1
- package/src/client/chat/cards.ts +186 -4
- package/src/client/chat/transcript.ts +1 -0
- package/src/client/locales.ts +22 -2
- package/src/client/sidechat/PendingCard.tsx +145 -0
- package/src/client/sidechat/SideChatPanel.tsx +27 -1
- package/src/client/sidechat/index.tsx +3 -0
- package/src/client/sidechat/notify.ts +91 -0
- package/src/client/sidechat/pending.ts +238 -0
- package/src/client/sidechat/sidechat.module.css +142 -1
package/lib/client.js
CHANGED
|
@@ -88,10 +88,20 @@ window.__ModuleLoader__.load({
|
|
|
88
88
|
modelSwitchTitle: "Switch the side chat model",
|
|
89
89
|
permChipTitle: "Permission mode",
|
|
90
90
|
permFullAccess: "Full access",
|
|
91
|
-
pendingNotice: "⚠
|
|
92
|
-
writeNotice: "
|
|
91
|
+
pendingNotice: "⚠ The side session has a pending approval/question — click to handle it in the main view",
|
|
92
|
+
writeNotice: "The side session shares the main session's permissions and can modify files (current mode: chip next to the input)",
|
|
93
|
+
pendingApprovalTitle: "Waiting for approval",
|
|
94
|
+
pendingApprovalDesc: "Tool {name} requests elevated execution",
|
|
95
|
+
pendingReject: "Reject",
|
|
96
|
+
pendingAllowOnce: "Allow once",
|
|
97
|
+
pendingQuestionTitle: "Question",
|
|
98
|
+
pendingPlanReview: "Plan review",
|
|
99
|
+
pendingQuestionSubmit: "Submit",
|
|
100
|
+
pendingQuestionCancel: "Cancel",
|
|
101
|
+
pendingCustomPlaceholder: "Custom answer…",
|
|
93
102
|
modelFollowsMain: "follows main session",
|
|
94
103
|
stopReply: "Stop",
|
|
104
|
+
sideChatDone: "「{title}」finished replying",
|
|
95
105
|
stopReplyTitle: "Stop the current reply",
|
|
96
106
|
send: "Send",
|
|
97
107
|
attachTitle: "Attach images",
|
|
@@ -214,8 +224,18 @@ window.__ModuleLoader__.load({
|
|
|
214
224
|
permFullAccess: "Full access",
|
|
215
225
|
pendingNotice: "⚠ 侧边会话有审批/提问待处理——点击跳到主视图处理",
|
|
216
226
|
writeNotice: "侧边会话与主会话同权限,可以修改文件(当前模式见输入框旁 chip)",
|
|
227
|
+
pendingApprovalTitle: "等待审批",
|
|
228
|
+
pendingApprovalDesc: "工具 {name} 请求越权执行",
|
|
229
|
+
pendingReject: "拒绝",
|
|
230
|
+
pendingAllowOnce: "允许一次",
|
|
231
|
+
pendingQuestionTitle: "提问",
|
|
232
|
+
pendingPlanReview: "计划审批",
|
|
233
|
+
pendingQuestionSubmit: "提交回答",
|
|
234
|
+
pendingQuestionCancel: "取消",
|
|
235
|
+
pendingCustomPlaceholder: "自定义回答…",
|
|
217
236
|
modelFollowsMain: "跟随主会话",
|
|
218
237
|
stopReply: "停止",
|
|
238
|
+
sideChatDone: "「{title}」回复完成",
|
|
219
239
|
stopReplyTitle: "停止当前回复",
|
|
220
240
|
send: "发送",
|
|
221
241
|
attachTitle: "添加图片附件",
|
|
@@ -1055,6 +1075,114 @@ window.__ModuleLoader__.load({
|
|
|
1055
1075
|
...typeof m.lang === "string" ? { lang: m.lang } : {}
|
|
1056
1076
|
};
|
|
1057
1077
|
}
|
|
1078
|
+
/**
|
|
1079
|
+
* FsDiffMeta 校验(0.1.2 diff 卡,dsh-tool-fs computeHunkDiffs 产物的忠实子集)。
|
|
1080
|
+
* 返回值三态:{diffs 非空} / 'empty'(空数组——write create/同内容覆写是合法值,
|
|
1081
|
+
* 客户端回退 args 整文件 diff)/ undefined(malformed——降级)。
|
|
1082
|
+
* 逐项校验,一项违规整卡降级(官方 narrowDiffs 同款)。
|
|
1083
|
+
*/
|
|
1084
|
+
function diffMetaOf(meta) {
|
|
1085
|
+
if (typeof meta !== "object" || meta === null || Array.isArray(meta)) return void 0;
|
|
1086
|
+
const m = meta;
|
|
1087
|
+
if (!Array.isArray(m.diffs)) return void 0;
|
|
1088
|
+
if (m.diffs.length === 0) return "empty";
|
|
1089
|
+
const diffs = [];
|
|
1090
|
+
for (const raw of m.diffs) {
|
|
1091
|
+
const d = raw;
|
|
1092
|
+
if (typeof d?.path !== "string") return void 0;
|
|
1093
|
+
if (d.oldText !== null && typeof d.oldText !== "string") return void 0;
|
|
1094
|
+
if (typeof d.newText !== "string") return void 0;
|
|
1095
|
+
diffs.push({
|
|
1096
|
+
path: d.path,
|
|
1097
|
+
oldText: d.oldText,
|
|
1098
|
+
newText: d.newText
|
|
1099
|
+
});
|
|
1100
|
+
}
|
|
1101
|
+
return { diffs };
|
|
1102
|
+
}
|
|
1103
|
+
/** SearchMeta 校验(0.1.2 search 卡;truncated/total 是硬字段;空结果合法)。 */
|
|
1104
|
+
function searchMetaOf(meta) {
|
|
1105
|
+
if (typeof meta !== "object" || meta === null || Array.isArray(meta)) return void 0;
|
|
1106
|
+
const m = meta;
|
|
1107
|
+
if (typeof m.truncated !== "boolean") return void 0;
|
|
1108
|
+
if (typeof m.total !== "number" || !Number.isInteger(m.total) || m.total < 0) return void 0;
|
|
1109
|
+
if (m.shape === "matches") {
|
|
1110
|
+
if (!Array.isArray(m.files)) return void 0;
|
|
1111
|
+
const files = [];
|
|
1112
|
+
for (const rawF of m.files) {
|
|
1113
|
+
const f = rawF;
|
|
1114
|
+
if (typeof f?.path !== "string" || !Array.isArray(f.matches)) return void 0;
|
|
1115
|
+
const matches = [];
|
|
1116
|
+
for (const rawM of f.matches) {
|
|
1117
|
+
const mm = rawM;
|
|
1118
|
+
if (typeof mm?.lineNumber !== "number" || !Number.isInteger(mm.lineNumber) || mm.lineNumber < 1) return void 0;
|
|
1119
|
+
if (typeof mm.line !== "string") return void 0;
|
|
1120
|
+
matches.push({
|
|
1121
|
+
lineNumber: mm.lineNumber,
|
|
1122
|
+
line: mm.line
|
|
1123
|
+
});
|
|
1124
|
+
}
|
|
1125
|
+
files.push({
|
|
1126
|
+
path: f.path,
|
|
1127
|
+
matches
|
|
1128
|
+
});
|
|
1129
|
+
}
|
|
1130
|
+
return {
|
|
1131
|
+
shape: "matches",
|
|
1132
|
+
files,
|
|
1133
|
+
truncated: m.truncated,
|
|
1134
|
+
total: m.total
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
if (m.shape === "paths") {
|
|
1138
|
+
if (!Array.isArray(m.paths) || !m.paths.every((p) => typeof p === "string")) return void 0;
|
|
1139
|
+
return {
|
|
1140
|
+
shape: "paths",
|
|
1141
|
+
paths: m.paths,
|
|
1142
|
+
truncated: m.truncated,
|
|
1143
|
+
total: m.total
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
/** WebSearchMeta 校验(sources 逐项 url 必填、title/snippet 可选;publishedAt 校验后丢弃)。 */
|
|
1148
|
+
function webSearchMetaOf(meta) {
|
|
1149
|
+
if (typeof meta !== "object" || meta === null || Array.isArray(meta)) return void 0;
|
|
1150
|
+
const m = meta;
|
|
1151
|
+
if (typeof m.truncated !== "boolean") return void 0;
|
|
1152
|
+
if (!Array.isArray(m.sources)) return void 0;
|
|
1153
|
+
const sources = [];
|
|
1154
|
+
for (const raw of m.sources) {
|
|
1155
|
+
const s = raw;
|
|
1156
|
+
if (typeof s?.url !== "string") return void 0;
|
|
1157
|
+
if (s.title !== void 0 && typeof s.title !== "string") return void 0;
|
|
1158
|
+
if (s.snippet !== void 0 && typeof s.snippet !== "string") return void 0;
|
|
1159
|
+
if (s.publishedAt !== void 0 && typeof s.publishedAt !== "string") return void 0;
|
|
1160
|
+
sources.push({
|
|
1161
|
+
url: s.url,
|
|
1162
|
+
...s.title !== void 0 ? { title: s.title } : {},
|
|
1163
|
+
...s.snippet !== void 0 ? { snippet: s.snippet } : {}
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1166
|
+
if (m.answer !== void 0 && typeof m.answer !== "string") return void 0;
|
|
1167
|
+
return {
|
|
1168
|
+
sources,
|
|
1169
|
+
truncated: m.truncated,
|
|
1170
|
+
...m.answer !== void 0 ? { answer: m.answer } : {}
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
/** WebFetchMeta 校验(url + 整数 statusCode + truncated 硬字段)。 */
|
|
1174
|
+
function webFetchMetaOf(meta) {
|
|
1175
|
+
if (typeof meta !== "object" || meta === null || Array.isArray(meta)) return void 0;
|
|
1176
|
+
const m = meta;
|
|
1177
|
+
if (typeof m.url !== "string") return void 0;
|
|
1178
|
+
if (typeof m.statusCode !== "number" || !Number.isInteger(m.statusCode)) return void 0;
|
|
1179
|
+
if (typeof m.truncated !== "boolean") return void 0;
|
|
1180
|
+
return {
|
|
1181
|
+
url: m.url,
|
|
1182
|
+
statusCode: m.statusCode,
|
|
1183
|
+
truncated: m.truncated
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1058
1186
|
/** argsRaw(JSON 字符串)里尽力提取展示字段。 */
|
|
1059
1187
|
function argsSummary(argsRaw) {
|
|
1060
1188
|
if (argsRaw === void 0 || argsRaw === "") return {};
|
|
@@ -1066,7 +1194,14 @@ window.__ModuleLoader__.load({
|
|
|
1066
1194
|
...typeof a.command === "string" ? { command: a.command } : {},
|
|
1067
1195
|
...typeof a.description === "string" ? { description: a.description } : {},
|
|
1068
1196
|
...typeof a.file_path === "string" ? { path: a.file_path } : typeof a.path === "string" ? { path: a.path } : {},
|
|
1069
|
-
...Array.isArray(a.todos) ? { todos: a.todos } : {}
|
|
1197
|
+
...Array.isArray(a.todos) ? { todos: a.todos } : {},
|
|
1198
|
+
...typeof a.content === "string" ? { content: a.content } : {},
|
|
1199
|
+
...typeof a.old_string === "string" ? { oldString: a.old_string } : {},
|
|
1200
|
+
...typeof a.new_string === "string" ? { newString: a.new_string } : {},
|
|
1201
|
+
...typeof a.pattern === "string" ? { pattern: a.pattern } : {},
|
|
1202
|
+
...typeof a.include === "string" ? { include: a.include } : {},
|
|
1203
|
+
...Array.isArray(a.queries) && a.queries.every((q) => typeof q === "string") ? { queries: a.queries } : {},
|
|
1204
|
+
...typeof a.url === "string" ? { url: a.url } : {}
|
|
1070
1205
|
};
|
|
1071
1206
|
} catch {
|
|
1072
1207
|
return {};
|
|
@@ -1111,6 +1246,75 @@ window.__ModuleLoader__.load({
|
|
|
1111
1246
|
items
|
|
1112
1247
|
};
|
|
1113
1248
|
}
|
|
1249
|
+
if ((name === "write" || name === "edit") && input.isError !== true) {
|
|
1250
|
+
const path = args.path;
|
|
1251
|
+
if (path !== void 0 && path.trim() !== "") {
|
|
1252
|
+
const dm = diffMetaOf(input.meta);
|
|
1253
|
+
if (dm !== void 0 && dm !== "empty") return {
|
|
1254
|
+
kind: "diff",
|
|
1255
|
+
title: displayTitle(`${name === "write" ? "Write" : "Edit"} ${path}`),
|
|
1256
|
+
diffs: dm.diffs,
|
|
1257
|
+
locations: [{ path }]
|
|
1258
|
+
};
|
|
1259
|
+
if (name === "write" && args.content !== void 0) return {
|
|
1260
|
+
kind: "diff",
|
|
1261
|
+
title: displayTitle(`Write ${path}`),
|
|
1262
|
+
diffs: [{
|
|
1263
|
+
path,
|
|
1264
|
+
oldText: null,
|
|
1265
|
+
newText: args.content
|
|
1266
|
+
}],
|
|
1267
|
+
locations: [{ path }]
|
|
1268
|
+
};
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
if ((name === "grep" || name === "glob") && input.isError !== true) {
|
|
1272
|
+
const sm = searchMetaOf(input.meta);
|
|
1273
|
+
const wantShape = name === "grep" ? "matches" : "paths";
|
|
1274
|
+
if (sm !== void 0 && sm.shape === wantShape && args.pattern !== void 0) {
|
|
1275
|
+
const where = args.path !== void 0 && args.path.trim() !== "" ? ` in ${shortPath(args.path)}` : "";
|
|
1276
|
+
const inc = name === "grep" && args.include !== void 0 && args.include.trim() !== "" ? ` (${args.include})` : "";
|
|
1277
|
+
const title = `${name === "grep" ? "Grep" : "Glob"} ${args.pattern}${where}${inc}`;
|
|
1278
|
+
return sm.shape === "matches" ? {
|
|
1279
|
+
kind: "search",
|
|
1280
|
+
title,
|
|
1281
|
+
shape: "matches",
|
|
1282
|
+
files: sm.files,
|
|
1283
|
+
truncated: sm.truncated,
|
|
1284
|
+
total: sm.total
|
|
1285
|
+
} : {
|
|
1286
|
+
kind: "search",
|
|
1287
|
+
title,
|
|
1288
|
+
shape: "paths",
|
|
1289
|
+
paths: sm.paths,
|
|
1290
|
+
truncated: sm.truncated,
|
|
1291
|
+
total: sm.total
|
|
1292
|
+
};
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
if (name === "web_search" && input.isError !== true) {
|
|
1296
|
+
const wm = webSearchMetaOf(input.meta);
|
|
1297
|
+
const queries = args.queries?.filter((q) => q.trim() !== "") ?? [];
|
|
1298
|
+
if (wm !== void 0 && queries.length > 0) return {
|
|
1299
|
+
kind: "web",
|
|
1300
|
+
title: queries.join(", "),
|
|
1301
|
+
webKind: "search",
|
|
1302
|
+
sources: wm.sources,
|
|
1303
|
+
truncated: wm.truncated,
|
|
1304
|
+
...wm.answer !== void 0 ? { answer: wm.answer } : {}
|
|
1305
|
+
};
|
|
1306
|
+
}
|
|
1307
|
+
if (name === "web_fetch" && input.isError !== true) {
|
|
1308
|
+
const wm = webFetchMetaOf(input.meta);
|
|
1309
|
+
if (wm !== void 0 && args.url !== void 0 && args.url.trim() !== "") return {
|
|
1310
|
+
kind: "web",
|
|
1311
|
+
title: args.url,
|
|
1312
|
+
webKind: "fetch",
|
|
1313
|
+
url: wm.url,
|
|
1314
|
+
statusCode: wm.statusCode,
|
|
1315
|
+
truncated: wm.truncated
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1114
1318
|
return {
|
|
1115
1319
|
kind: "generic",
|
|
1116
1320
|
title: args.path !== void 0 ? `${name} · ${shortPath(args.path)}` : args.command ?? name,
|
|
@@ -1118,19 +1322,22 @@ window.__ModuleLoader__.load({
|
|
|
1118
1322
|
bodyText: input.rawText === "" ? void 0 : input.rawText
|
|
1119
1323
|
};
|
|
1120
1324
|
}
|
|
1121
|
-
/** 工具名 → 图标类别的静态映射(0.1.2 没有 callView.kind 可用)。
|
|
1325
|
+
/** 工具名 → 图标类别的静态映射(0.1.2 没有 callView.kind 可用)。
|
|
1326
|
+
* wire 名实证:str_replace_editor 是下划线(uitool client.js L381);
|
|
1327
|
+
* web_search 的 0.1.1 wire kind 是 'search'(presentSearchCall),
|
|
1328
|
+
* 'fetch' 是 web_fetch 的(presentFetchCall)。 */
|
|
1122
1329
|
const KIND_BY_NAME = {
|
|
1123
1330
|
read: "read",
|
|
1124
1331
|
write: "edit",
|
|
1125
1332
|
edit: "edit",
|
|
1126
|
-
|
|
1333
|
+
str_replace_editor: "edit",
|
|
1127
1334
|
bash: "execute",
|
|
1128
1335
|
"bash-persistent": "execute",
|
|
1129
1336
|
pwsh: "execute",
|
|
1130
1337
|
"pwsh-persistent": "execute",
|
|
1131
1338
|
grep: "search",
|
|
1132
1339
|
glob: "search",
|
|
1133
|
-
web_search: "
|
|
1340
|
+
web_search: "search",
|
|
1134
1341
|
web_fetch: "fetch"
|
|
1135
1342
|
};
|
|
1136
1343
|
//#endregion
|
|
@@ -1221,7 +1428,8 @@ window.__ModuleLoader__.load({
|
|
|
1221
1428
|
name: toolName,
|
|
1222
1429
|
argsRaw: typeof call?.argsRaw === "string" ? call.argsRaw : void 0,
|
|
1223
1430
|
meta: n.meta,
|
|
1224
|
-
rawText: text
|
|
1431
|
+
rawText: text,
|
|
1432
|
+
...n.isError === true ? { isError: true } : {}
|
|
1225
1433
|
});
|
|
1226
1434
|
return {
|
|
1227
1435
|
key: seqKey("t", n),
|
|
@@ -1476,7 +1684,7 @@ window.__ModuleLoader__.load({
|
|
|
1476
1684
|
}
|
|
1477
1685
|
//#endregion
|
|
1478
1686
|
//#region \0dsh-css:/home/runner/work/dsh-sidenote/dsh-sidenote/src/client/sidechat/sidechat.module.css.mjs
|
|
1479
|
-
const css$1 = "._5KEEsG_root{height:100%;color:var(--dsw-alias-label-primary);flex-direction:column;font-size:13px;display:flex;position:relative}._5KEEsG_body{flex-direction:column;flex:1;padding:12px 10px;display:flex;overflow-y:auto}._5KEEsG_transcript{flex-direction:column;gap:10px;display:flex}._5KEEsG_empty,._5KEEsG_stateScreen{text-align:center;flex-direction:column;flex:1;justify-content:center;align-items:center;gap:8px;padding:24px 16px;display:flex}._5KEEsG_emptyIcon{color:var(--dsw-alias-label-tertiary)}._5KEEsG_emptyTitle{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:600}._5KEEsG_emptyText{color:var(--dsw-alias-label-tertiary);max-width:240px;font-size:12px;line-height:1.6}._5KEEsG_stateDetail{color:var(--dsw-alias-state-error-primary);word-break:break-word;max-width:260px;font-size:12px;line-height:1.6}._5KEEsG_userRow{justify-content:flex-end;display:flex}._5KEEsG_userBubble{background:var(--dsw-specific-bubble,#edf3fe);max-width:88%;color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;border-radius:16px;padding:8px 12px;font-size:13px;line-height:1.55}._5KEEsG_assistantRow{justify-content:flex-start;display:flex;position:relative}._5KEEsG_rowActions{opacity:0;z-index:2;transition:opacity .12s ease-out;position:absolute;top:-8px;right:0}._5KEEsG_assistantRow:hover ._5KEEsG_rowActions{opacity:1}._5KEEsG_reflowButton{border:1px solid var(--dsw-alias-border-l1,#0000001a);background:var(--dsw-alias-bg-layer-1,#fff);width:22px;height:22px;color:var(--dsw-alias-label-tertiary,#8f959e);cursor:pointer;border-radius:999px;place-items:center;padding:0;display:grid;box-shadow:0 2px 8px #00000014}._5KEEsG_reflowButton:hover{color:var(--dsw-alias-state-business-primary,#2f88ff);border-color:var(--dsw-alias-state-business-primary,#2f88ff)}._5KEEsG_assistantBody{word-break:break-word;max-width:100%;font-size:13px;line-height:1.6}._5KEEsG_reasoning{border-left:3px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);margin-bottom:6px;padding-left:8px;font-size:12px}._5KEEsG_reasoning>summary{cursor:pointer;user-select:none}._5KEEsG_reasoningBody{white-space:pre-wrap;word-break:break-word;color:var(--dsw-alias-label-tertiary);margin-top:2px;padding-bottom:2px;padding-left:22px}._5KEEsG_streamingHint{color:var(--dsw-alias-label-dimmed)}._5KEEsG_toolCard{font-size:12px}._5KEEsG_toolHead{color:var(--dsw-alias-label-secondary);align-items:center;gap:6px;font-size:12px;display:flex}._5KEEsG_toolError{color:var(--dsw-alias-state-error-primary)}._5KEEsG_toolRunning{color:var(--dsw-alias-label-tertiary)}._5KEEsG_toolBody{color:var(--dsw-alias-label-tertiary);white-space:pre-wrap;word-break:break-word;max-height:160px;padding:2px 0 2px 22px;font-size:12px;overflow-y:auto}._5KEEsG_errorRow{color:var(--dsw-alias-state-error-primary);white-space:pre-wrap;padding:4px 2px;font-size:12px}._5KEEsG_noticeRow{color:var(--dsw-alias-label-dimmed);text-align:center;padding:2px 0;font-size:12px}._5KEEsG_composer{border-top:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:6px;padding:8px 10px;display:flex;position:relative}._5KEEsG_composerCard{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:14px;flex-direction:column;gap:2px;padding:4px 6px 6px;transition:border-color .12s;display:flex}._5KEEsG_composerCard:focus-within{border-color:var(--dsw-alias-state-business-primary)}._5KEEsG_input{resize:none;width:100%;min-height:36px;max-height:160px;color:var(--dsw-alias-label-primary);font:inherit;box-sizing:border-box;background:0 0;border:none;padding:6px 6px 2px}._5KEEsG_input:focus{outline:none}._5KEEsG_composerFoot{justify-content:space-between;align-items:center;gap:8px;padding:0 2px;display:flex}._5KEEsG_modelLabel{color:var(--dsw-alias-label-dimmed);text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}._5KEEsG_sendButton,._5KEEsG_stopButton{appearance:none;background:var(--dsw-alias-button-info-fill);color:#fff;cursor:pointer;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;width:28px;height:28px;padding:0;display:inline-flex}._5KEEsG_sendButton:disabled{opacity:.45;cursor:default}._5KEEsG_headerSide{border:1px solid var(--dsw-alias-border-l1,#0000001a);color:var(--dsw-alias-label-secondary,#3f454d);cursor:pointer;user-select:none;background:0 0;border-radius:999px;align-items:center;gap:5px;padding:3px 10px;font-size:12px;line-height:18px;display:inline-flex}._5KEEsG_headerSide:hover{background:var(--dsw-alias-interactive-bg-hover,#0000000d);color:var(--dsw-alias-label-primary,#1f2329)}._5KEEsG_sentChipRow{align-items:center;gap:6px;margin-right:8px;display:inline-flex}._5KEEsG_sentChip{border:1px solid var(--dsw-alias-border-l1,#0000001a);background:var(--dsw-alias-interactive-bg-hover,#0000000d);color:var(--dsw-alias-label-secondary,#3f454d);user-select:none;border-radius:999px;align-items:center;gap:4px;padding:1px 8px;font-size:11px;line-height:16px;display:inline-flex}._5KEEsG_flowRow{font-size:12px}._5KEEsG_rowPreview{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-dimmed);flex:1;margin-left:8px;font-size:12px;overflow:hidden}._5KEEsG_flowRowError{color:var(--dsw-alias-state-error-primary)}._5KEEsG_todoBody{flex-direction:column;gap:3px;padding:2px 0 4px 22px;display:flex}._5KEEsG_todoItem{align-items:baseline;gap:7px;min-width:0;font-size:12px;line-height:1.5;display:flex}._5KEEsG_todoDot{background:var(--dsw-alias-label-dimmed);border-radius:50%;flex:none;width:6px;height:6px;transform:translateY(-1px)}._5KEEsG_todoDot[data-status=completed]{background:var(--dsw-alias-state-success-primary,#34a853)}._5KEEsG_todoDot[data-status=in_progress]{background:var(--dsw-alias-state-business-primary)}._5KEEsG_todoText[data-status=completed]{color:var(--dsw-alias-label-dimmed)}._5KEEsG_toolGenericBody{flex-direction:column;gap:6px;padding:4px 0 4px 22px;display:flex}._5KEEsG_toolBodyText{color:var(--dsw-alias-label-secondary);white-space:pre-wrap;word-break:break-word;font-size:12px;line-height:1.55;font-family:var(--dsw-alias-font-mono,ui-monospace, monospace);margin:0}._5KEEsG_toolLocations{color:var(--dsw-alias-label-tertiary);white-space:pre-wrap;word-break:break-all;font-size:11px}._5KEEsG_inheritedBody{border-top:1px dashed var(--dsw-alias-border-l2);opacity:.92;padding:6px 0 2px}._5KEEsG_densityRow{justify-content:flex-end;align-items:center;padding:2px 2px 4px;display:flex}._5KEEsG_densityToggle{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;padding:2px 6px;font-size:11px}._5KEEsG_densityToggle:hover{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2)}._5KEEsG_jumpBottom{z-index:5;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);cursor:pointer;border-radius:999px;padding:3px 10px;font-size:11px;position:absolute;bottom:96px;right:12px;box-shadow:0 2px 8px #0000001f}._5KEEsG_jumpBottom:hover{background:var(--dsw-alias-bg-layer-2)}._5KEEsG_modelSelect{color:var(--dsw-alias-label-secondary);cursor:pointer;white-space:nowrap;background:0 0;border:none;border-radius:6px;align-items:center;gap:3px;max-width:180px;padding:3px 6px;font-size:12px;display:inline-flex;overflow:hidden}._5KEEsG_modelSelect>span:first-child{text-overflow:ellipsis;overflow:hidden}._5KEEsG_modelSelect>svg{color:var(--dsw-alias-label-dimmed);flex:none}._5KEEsG_modelSelect:hover{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2)}._5KEEsG_composerChips{align-items:center;gap:4px;min-width:0;display:inline-flex;overflow:hidden}._5KEEsG_slashMenu{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);z-index:20;border-radius:10px;max-height:260px;margin-bottom:6px;padding:4px;position:absolute;bottom:100%;left:8px;right:8px;overflow-y:auto;box-shadow:0 8px 24px #00000024}._5KEEsG_slashGroupTitle{color:var(--dsw-alias-label-tertiary);text-transform:none;padding:4px 8px 2px;font-size:11px}._5KEEsG_slashItem,._5KEEsG_slashItemActive{text-align:left;cursor:pointer;width:100%;color:var(--dsw-alias-label-primary);background:0 0;border:none;border-radius:6px;align-items:baseline;gap:8px;padding:6px 8px;font-size:13px;display:flex}._5KEEsG_slashItemActive,._5KEEsG_slashItem:hover{background:var(--dsw-alias-interactive-bg-hover)}._5KEEsG_slashItemName{flex:none;font-weight:500}._5KEEsG_slashItemDetail{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}._5KEEsG_attachRail{flex-wrap:wrap;gap:6px;padding:2px 0;display:flex}._5KEEsG_attachThumb{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;width:44px;height:44px;position:relative;overflow:hidden}._5KEEsG_attachImg{object-fit:cover;width:100%;height:100%;display:block}._5KEEsG_attachRemove{color:#fff;cursor:pointer;background:#0000008c;border:none;border-radius:999px;place-items:center;width:16px;height:16px;padding:0;font-size:11px;line-height:1;display:grid;position:absolute;top:1px;right:1px}._5KEEsG_attachButton{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:6px;padding:4px;display:inline-flex}._5KEEsG_attachButton:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}._5KEEsG_pendingBar{border:1px solid var(--dsw-alias-state-warning-primary,#d4a017);background:var(--dsw-alias-bg-layer-2);width:calc(100% - 16px);color:var(--dsw-alias-state-warning-primary,#d4a017);text-align:left;cursor:pointer;border-radius:8px;margin:0 8px 6px;padding:6px 10px;font-size:12px;display:block}._5KEEsG_pendingBar:hover{background:var(--dsw-alias-bg-layer-3)}._5KEEsG_writeNotice{background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-tertiary);border-radius:8px;align-items:center;gap:8px;margin:0 8px 6px;padding:6px 10px;font-size:12px;display:flex}._5KEEsG_writeNoticeClose{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;margin-left:auto;padding:0 4px;font-size:13px}._5KEEsG_parentStrip{border:none;border-bottom:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:100%;color:var(--dsw-alias-label-secondary);cursor:pointer;text-align:left;align-items:center;gap:6px;padding:5px 12px;font-size:11px;display:flex}._5KEEsG_parentStrip:hover{background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary)}._5KEEsG_dotRunning,._5KEEsG_dotPending,._5KEEsG_dotIdle{border-radius:999px;flex:none;width:7px;height:7px}._5KEEsG_dotRunning{background:var(--dsw-alias-state-business-primary,#2f88ff);animation:1.2s ease-in-out infinite _5KEEsG_sidechat-pulse}._5KEEsG_dotPending{background:var(--dsw-alias-state-warning-primary,#d4a017)}._5KEEsG_dotIdle{background:var(--dsw-alias-label-dimmed)}@keyframes _5KEEsG_sidechat-pulse{50%{opacity:.45}}._5KEEsG_actionGroup{gap:2px;margin-right:auto;display:inline-flex}";
|
|
1687
|
+
const css$1 = "._5KEEsG_root{height:100%;color:var(--dsw-alias-label-primary);flex-direction:column;font-size:13px;display:flex;position:relative}._5KEEsG_body{flex-direction:column;flex:1;padding:12px 10px;display:flex;overflow-y:auto}._5KEEsG_transcript{flex-direction:column;gap:10px;display:flex}._5KEEsG_empty,._5KEEsG_stateScreen{text-align:center;flex-direction:column;flex:1;justify-content:center;align-items:center;gap:8px;padding:24px 16px;display:flex}._5KEEsG_emptyIcon{color:var(--dsw-alias-label-tertiary)}._5KEEsG_emptyTitle{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:600}._5KEEsG_emptyText{color:var(--dsw-alias-label-tertiary);max-width:240px;font-size:12px;line-height:1.6}._5KEEsG_stateDetail{color:var(--dsw-alias-state-error-primary);word-break:break-word;max-width:260px;font-size:12px;line-height:1.6}._5KEEsG_userRow{justify-content:flex-end;display:flex}._5KEEsG_userBubble{background:var(--dsw-specific-bubble,#edf3fe);max-width:88%;color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;border-radius:16px;padding:8px 12px;font-size:13px;line-height:1.55}._5KEEsG_assistantRow{justify-content:flex-start;display:flex;position:relative}._5KEEsG_rowActions{opacity:0;z-index:2;transition:opacity .12s ease-out;position:absolute;top:-8px;right:0}._5KEEsG_assistantRow:hover ._5KEEsG_rowActions{opacity:1}._5KEEsG_reflowButton{border:1px solid var(--dsw-alias-border-l1,#0000001a);background:var(--dsw-alias-bg-layer-1,#fff);width:22px;height:22px;color:var(--dsw-alias-label-tertiary,#8f959e);cursor:pointer;border-radius:999px;place-items:center;padding:0;display:grid;box-shadow:0 2px 8px #00000014}._5KEEsG_reflowButton:hover{color:var(--dsw-alias-state-business-primary,#2f88ff);border-color:var(--dsw-alias-state-business-primary,#2f88ff)}._5KEEsG_assistantBody{word-break:break-word;max-width:100%;font-size:13px;line-height:1.6}._5KEEsG_reasoning{border-left:3px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);margin-bottom:6px;padding-left:8px;font-size:12px}._5KEEsG_reasoning>summary{cursor:pointer;user-select:none}._5KEEsG_reasoningBody{white-space:pre-wrap;word-break:break-word;color:var(--dsw-alias-label-tertiary);margin-top:2px;padding-bottom:2px;padding-left:22px}._5KEEsG_streamingHint{color:var(--dsw-alias-label-dimmed)}._5KEEsG_toolCard{font-size:12px}._5KEEsG_toolHead{color:var(--dsw-alias-label-secondary);align-items:center;gap:6px;font-size:12px;display:flex}._5KEEsG_toolError{color:var(--dsw-alias-state-error-primary)}._5KEEsG_toolRunning{color:var(--dsw-alias-label-tertiary)}._5KEEsG_toolBody{color:var(--dsw-alias-label-tertiary);white-space:pre-wrap;word-break:break-word;max-height:160px;padding:2px 0 2px 22px;font-size:12px;overflow-y:auto}._5KEEsG_errorRow{color:var(--dsw-alias-state-error-primary);white-space:pre-wrap;padding:4px 2px;font-size:12px}._5KEEsG_noticeRow{color:var(--dsw-alias-label-dimmed);text-align:center;padding:2px 0;font-size:12px}._5KEEsG_composer{border-top:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:6px;padding:8px 10px;display:flex;position:relative}._5KEEsG_composerCard{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:14px;flex-direction:column;gap:2px;padding:4px 6px 6px;transition:border-color .12s;display:flex}._5KEEsG_composerCard:focus-within{border-color:var(--dsw-alias-state-business-primary)}._5KEEsG_input{resize:none;width:100%;min-height:36px;max-height:160px;color:var(--dsw-alias-label-primary);font:inherit;box-sizing:border-box;background:0 0;border:none;padding:6px 6px 2px}._5KEEsG_input:focus{outline:none}._5KEEsG_composerFoot{justify-content:space-between;align-items:center;gap:8px;padding:0 2px;display:flex}._5KEEsG_modelLabel{color:var(--dsw-alias-label-dimmed);text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}._5KEEsG_sendButton,._5KEEsG_stopButton{appearance:none;background:var(--dsw-alias-button-info-fill);color:#fff;cursor:pointer;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;width:28px;height:28px;padding:0;display:inline-flex}._5KEEsG_sendButton:disabled{opacity:.45;cursor:default}._5KEEsG_headerSide{border:1px solid var(--dsw-alias-border-l1,#0000001a);color:var(--dsw-alias-label-secondary,#3f454d);cursor:pointer;user-select:none;background:0 0;border-radius:999px;align-items:center;gap:5px;padding:3px 10px;font-size:12px;line-height:18px;display:inline-flex}._5KEEsG_headerSide:hover{background:var(--dsw-alias-interactive-bg-hover,#0000000d);color:var(--dsw-alias-label-primary,#1f2329)}._5KEEsG_sentChipRow{align-items:center;gap:6px;margin-right:8px;display:inline-flex}._5KEEsG_sentChip{border:1px solid var(--dsw-alias-border-l1,#0000001a);background:var(--dsw-alias-interactive-bg-hover,#0000000d);color:var(--dsw-alias-label-secondary,#3f454d);user-select:none;border-radius:999px;align-items:center;gap:4px;padding:1px 8px;font-size:11px;line-height:16px;display:inline-flex}._5KEEsG_flowRow{font-size:12px}._5KEEsG_rowPreview{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-dimmed);flex:1;margin-left:8px;font-size:12px;overflow:hidden}._5KEEsG_flowRowError{color:var(--dsw-alias-state-error-primary)}._5KEEsG_todoBody{flex-direction:column;gap:3px;padding:2px 0 4px 22px;display:flex}._5KEEsG_todoItem{align-items:baseline;gap:7px;min-width:0;font-size:12px;line-height:1.5;display:flex}._5KEEsG_todoDot{background:var(--dsw-alias-label-dimmed);border-radius:50%;flex:none;width:6px;height:6px;transform:translateY(-1px)}._5KEEsG_todoDot[data-status=completed]{background:var(--dsw-alias-state-success-primary,#34a853)}._5KEEsG_todoDot[data-status=in_progress]{background:var(--dsw-alias-state-business-primary)}._5KEEsG_todoText[data-status=completed]{color:var(--dsw-alias-label-dimmed)}._5KEEsG_toolGenericBody{flex-direction:column;gap:6px;padding:4px 0 4px 22px;display:flex}._5KEEsG_toolBodyText{color:var(--dsw-alias-label-secondary);white-space:pre-wrap;word-break:break-word;font-size:12px;line-height:1.55;font-family:var(--dsw-alias-font-mono,ui-monospace, monospace);margin:0}._5KEEsG_toolLocations{color:var(--dsw-alias-label-tertiary);white-space:pre-wrap;word-break:break-all;font-size:11px}._5KEEsG_inheritedBody{border-top:1px dashed var(--dsw-alias-border-l2);opacity:.92;padding:6px 0 2px}._5KEEsG_densityRow{justify-content:flex-end;align-items:center;padding:2px 2px 4px;display:flex}._5KEEsG_densityToggle{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;padding:2px 6px;font-size:11px}._5KEEsG_densityToggle:hover{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2)}._5KEEsG_jumpBottom{z-index:5;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);cursor:pointer;border-radius:999px;padding:3px 10px;font-size:11px;position:absolute;bottom:96px;right:12px;box-shadow:0 2px 8px #0000001f}._5KEEsG_jumpBottom:hover{background:var(--dsw-alias-bg-layer-2)}._5KEEsG_modelSelect{color:var(--dsw-alias-label-secondary);cursor:pointer;white-space:nowrap;background:0 0;border:none;border-radius:6px;align-items:center;gap:3px;max-width:180px;padding:3px 6px;font-size:12px;display:inline-flex;overflow:hidden}._5KEEsG_modelSelect>span:first-child{text-overflow:ellipsis;overflow:hidden}._5KEEsG_modelSelect>svg{color:var(--dsw-alias-label-dimmed);flex:none}._5KEEsG_modelSelect:hover{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2)}._5KEEsG_composerChips{align-items:center;gap:4px;min-width:0;display:inline-flex;overflow:hidden}._5KEEsG_slashMenu{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);z-index:20;border-radius:10px;max-height:260px;margin-bottom:6px;padding:4px;position:absolute;bottom:100%;left:8px;right:8px;overflow-y:auto;box-shadow:0 8px 24px #00000024}._5KEEsG_slashGroupTitle{color:var(--dsw-alias-label-tertiary);text-transform:none;padding:4px 8px 2px;font-size:11px}._5KEEsG_slashItem,._5KEEsG_slashItemActive{text-align:left;cursor:pointer;width:100%;color:var(--dsw-alias-label-primary);background:0 0;border:none;border-radius:6px;align-items:baseline;gap:8px;padding:6px 8px;font-size:13px;display:flex}._5KEEsG_slashItemActive,._5KEEsG_slashItem:hover{background:var(--dsw-alias-interactive-bg-hover)}._5KEEsG_slashItemName{flex:none;font-weight:500}._5KEEsG_slashItemDetail{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}._5KEEsG_attachRail{flex-wrap:wrap;gap:6px;padding:2px 0;display:flex}._5KEEsG_attachThumb{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;width:44px;height:44px;position:relative;overflow:hidden}._5KEEsG_attachImg{object-fit:cover;width:100%;height:100%;display:block}._5KEEsG_attachRemove{color:#fff;cursor:pointer;background:#0000008c;border:none;border-radius:999px;place-items:center;width:16px;height:16px;padding:0;font-size:11px;line-height:1;display:grid;position:absolute;top:1px;right:1px}._5KEEsG_attachButton{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:6px;padding:4px;display:inline-flex}._5KEEsG_attachButton:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}._5KEEsG_pendingCard{border:1px solid var(--dsw-alias-border-l2);border-left:3px solid var(--dsw-alias-state-warning-primary,#e8a13a);background:var(--dsw-alias-bg-layer-2);border-radius:10px;flex-direction:column;gap:6px;margin:0 10px 6px;padding:10px 12px;font-size:12px;display:flex}._5KEEsG_pendingHead{color:var(--dsw-alias-state-warning-primary,#e8a13a);align-items:center;gap:6px;display:flex}._5KEEsG_pendingTitle{color:var(--dsw-alias-label-primary);font-weight:600}._5KEEsG_pendingDesc{color:var(--dsw-alias-label-secondary)}._5KEEsG_pendingReason{color:var(--dsw-alias-label-tertiary);white-space:pre-wrap;word-break:break-word}._5KEEsG_pendingQuestion{flex-direction:column;gap:4px;padding:4px 0;display:flex}._5KEEsG_pendingQHeader{color:var(--dsw-alias-label-primary);font-weight:600}._5KEEsG_pendingQText{color:var(--dsw-alias-label-secondary)}._5KEEsG_pendingOption{text-align:left;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border-radius:6px;flex-direction:column;align-items:flex-start;gap:2px;padding:5px 8px;font-size:12px;display:flex}._5KEEsG_pendingOption:hover{background:var(--dsw-alias-interactive-bg-hover,#0000000d)}._5KEEsG_pendingOptionActive{text-align:left;border:1px solid var(--dsw-alias-state-business-primary);background:var(--dsw-alias-interactive-bg-hover,#0000000d);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;flex-direction:column;align-items:flex-start;gap:2px;padding:5px 8px;font-size:12px;display:flex}._5KEEsG_pendingOptionDesc{color:var(--dsw-alias-label-dimmed);font-size:11px}._5KEEsG_pendingCustom{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);font-size:12px;font:inherit;background:0 0;border-radius:6px;padding:5px 8px}._5KEEsG_pendingCustom:focus{border-color:var(--dsw-alias-state-business-primary);outline:none}._5KEEsG_pendingActions{justify-content:flex-end;gap:8px;margin-top:2px;display:flex}._5KEEsG_pendingBtnGhost{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border-radius:6px;padding:4px 12px;font-size:12px}._5KEEsG_pendingBtnPrimary{background:var(--dsw-alias-button-info-fill);color:#fff;cursor:pointer;border:none;border-radius:6px;padding:4px 12px;font-size:12px}._5KEEsG_pendingBtnGhost:disabled,._5KEEsG_pendingBtnPrimary:disabled{opacity:.5;cursor:default}._5KEEsG_pendingBar{border:1px solid var(--dsw-alias-state-warning-primary,#d4a017);background:var(--dsw-alias-bg-layer-2);width:calc(100% - 16px);color:var(--dsw-alias-state-warning-primary,#d4a017);text-align:left;cursor:pointer;border-radius:8px;margin:0 8px 6px;padding:6px 10px;font-size:12px;display:block}._5KEEsG_pendingBar:hover{background:var(--dsw-alias-bg-layer-3)}._5KEEsG_writeNotice{background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-tertiary);border-radius:8px;align-items:center;gap:8px;margin:0 8px 6px;padding:6px 10px;font-size:12px;display:flex}._5KEEsG_writeNoticeClose{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;margin-left:auto;padding:0 4px;font-size:13px}._5KEEsG_parentStrip{border:none;border-bottom:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:100%;color:var(--dsw-alias-label-secondary);cursor:pointer;text-align:left;align-items:center;gap:6px;padding:5px 12px;font-size:11px;display:flex}._5KEEsG_parentStrip:hover{background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary)}._5KEEsG_dotRunning,._5KEEsG_dotPending,._5KEEsG_dotIdle{border-radius:999px;flex:none;width:7px;height:7px}._5KEEsG_dotRunning{background:var(--dsw-alias-state-business-primary,#2f88ff);animation:1.2s ease-in-out infinite _5KEEsG_sidechat-pulse}._5KEEsG_dotPending{background:var(--dsw-alias-state-warning-primary,#d4a017)}._5KEEsG_dotIdle{background:var(--dsw-alias-label-dimmed)}@keyframes _5KEEsG_sidechat-pulse{50%{opacity:.45}}._5KEEsG_actionGroup{gap:2px;margin-right:auto;display:inline-flex}";
|
|
1480
1688
|
const tagId$1 = "dsh-sidenote/sidechat.module.css";
|
|
1481
1689
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
1482
1690
|
const tag = document.createElement("style");
|
|
@@ -1486,77 +1694,92 @@ window.__ModuleLoader__.load({
|
|
|
1486
1694
|
document.head.appendChild(tag);
|
|
1487
1695
|
}
|
|
1488
1696
|
var sidechat_module_css_default = {
|
|
1489
|
-
"
|
|
1490
|
-
"
|
|
1491
|
-
"
|
|
1492
|
-
"
|
|
1493
|
-
"
|
|
1494
|
-
"slashItemDetail": "_5KEEsG_slashItemDetail",
|
|
1495
|
-
"composerFoot": "_5KEEsG_composerFoot",
|
|
1496
|
-
"assistantRow": "_5KEEsG_assistantRow",
|
|
1697
|
+
"composerCard": "_5KEEsG_composerCard",
|
|
1698
|
+
"streamingHint": "_5KEEsG_streamingHint",
|
|
1699
|
+
"stopButton": "_5KEEsG_stopButton",
|
|
1700
|
+
"transcript": "_5KEEsG_transcript",
|
|
1701
|
+
"rowPreview": "_5KEEsG_rowPreview",
|
|
1497
1702
|
"toolGenericBody": "_5KEEsG_toolGenericBody",
|
|
1498
|
-
"
|
|
1499
|
-
"
|
|
1500
|
-
"emptyIcon": "_5KEEsG_emptyIcon",
|
|
1703
|
+
"densityRow": "_5KEEsG_densityRow",
|
|
1704
|
+
"pendingReason": "_5KEEsG_pendingReason",
|
|
1501
1705
|
"toolError": "_5KEEsG_toolError",
|
|
1706
|
+
"pendingOptionDesc": "_5KEEsG_pendingOptionDesc",
|
|
1502
1707
|
"empty": "_5KEEsG_empty",
|
|
1503
|
-
"
|
|
1504
|
-
"
|
|
1505
|
-
"
|
|
1506
|
-
"streamingHint": "_5KEEsG_streamingHint",
|
|
1507
|
-
"input": "_5KEEsG_input",
|
|
1508
|
-
"sendButton": "_5KEEsG_sendButton",
|
|
1509
|
-
"todoBody": "_5KEEsG_todoBody",
|
|
1510
|
-
"parentStrip": "_5KEEsG_parentStrip",
|
|
1511
|
-
"dotRunning": "_5KEEsG_dotRunning",
|
|
1708
|
+
"stateScreen": "_5KEEsG_stateScreen",
|
|
1709
|
+
"slashMenu": "_5KEEsG_slashMenu",
|
|
1710
|
+
"userBubble": "_5KEEsG_userBubble",
|
|
1512
1711
|
"dotPending": "_5KEEsG_dotPending",
|
|
1513
|
-
"
|
|
1514
|
-
"
|
|
1712
|
+
"pendingOptionActive": "_5KEEsG_pendingOptionActive",
|
|
1713
|
+
"pendingDesc": "_5KEEsG_pendingDesc",
|
|
1714
|
+
"pendingActions": "_5KEEsG_pendingActions",
|
|
1715
|
+
"todoDot": "_5KEEsG_todoDot",
|
|
1515
1716
|
"todoText": "_5KEEsG_todoText",
|
|
1516
|
-
"
|
|
1717
|
+
"emptyIcon": "_5KEEsG_emptyIcon",
|
|
1718
|
+
"reflowButton": "_5KEEsG_reflowButton",
|
|
1719
|
+
"pendingBtnPrimary": "_5KEEsG_pendingBtnPrimary",
|
|
1720
|
+
"reasoningBody": "_5KEEsG_reasoningBody",
|
|
1517
1721
|
"inheritedBody": "_5KEEsG_inheritedBody",
|
|
1722
|
+
"attachRail": "_5KEEsG_attachRail",
|
|
1723
|
+
"pendingBtnGhost": "_5KEEsG_pendingBtnGhost",
|
|
1724
|
+
"dotIdle": "_5KEEsG_dotIdle",
|
|
1725
|
+
"slashItemName": "_5KEEsG_slashItemName",
|
|
1726
|
+
"sendButton": "_5KEEsG_sendButton",
|
|
1727
|
+
"slashItemActive": "_5KEEsG_slashItemActive",
|
|
1728
|
+
"stateDetail": "_5KEEsG_stateDetail",
|
|
1729
|
+
"emptyTitle": "_5KEEsG_emptyTitle",
|
|
1730
|
+
"pendingCustom": "_5KEEsG_pendingCustom",
|
|
1731
|
+
"dotRunning": "_5KEEsG_dotRunning",
|
|
1732
|
+
"densityToggle": "_5KEEsG_densityToggle",
|
|
1733
|
+
"pendingOption": "_5KEEsG_pendingOption",
|
|
1734
|
+
"modelLabel": "_5KEEsG_modelLabel",
|
|
1735
|
+
"body": "_5KEEsG_body",
|
|
1736
|
+
"toolHead": "_5KEEsG_toolHead",
|
|
1737
|
+
"reasoning": "_5KEEsG_reasoning",
|
|
1738
|
+
"pendingQHeader": "_5KEEsG_pendingQHeader",
|
|
1739
|
+
"writeNotice": "_5KEEsG_writeNotice",
|
|
1740
|
+
"input": "_5KEEsG_input",
|
|
1741
|
+
"sentChipRow": "_5KEEsG_sentChipRow",
|
|
1518
1742
|
"todoItem": "_5KEEsG_todoItem",
|
|
1743
|
+
"composer": "_5KEEsG_composer",
|
|
1744
|
+
"slashItem": "_5KEEsG_slashItem",
|
|
1745
|
+
"flowRow": "_5KEEsG_flowRow",
|
|
1746
|
+
"pendingHead": "_5KEEsG_pendingHead",
|
|
1747
|
+
"composerChips": "_5KEEsG_composerChips",
|
|
1519
1748
|
"errorRow": "_5KEEsG_errorRow",
|
|
1520
|
-
"
|
|
1521
|
-
"
|
|
1522
|
-
"
|
|
1523
|
-
"
|
|
1524
|
-
"
|
|
1525
|
-
"
|
|
1749
|
+
"slashItemDetail": "_5KEEsG_slashItemDetail",
|
|
1750
|
+
"toolRunning": "_5KEEsG_toolRunning",
|
|
1751
|
+
"noticeRow": "_5KEEsG_noticeRow",
|
|
1752
|
+
"pendingTitle": "_5KEEsG_pendingTitle",
|
|
1753
|
+
"jumpBottom": "_5KEEsG_jumpBottom",
|
|
1754
|
+
"flowRowError": "_5KEEsG_flowRowError",
|
|
1755
|
+
"sidechat-pulse": "_5KEEsG_sidechat-pulse",
|
|
1756
|
+
"root": "_5KEEsG_root",
|
|
1526
1757
|
"emptyText": "_5KEEsG_emptyText",
|
|
1527
|
-
"
|
|
1528
|
-
"
|
|
1758
|
+
"slashGroupTitle": "_5KEEsG_slashGroupTitle",
|
|
1759
|
+
"toolCard": "_5KEEsG_toolCard",
|
|
1529
1760
|
"assistantBody": "_5KEEsG_assistantBody",
|
|
1761
|
+
"composerFoot": "_5KEEsG_composerFoot",
|
|
1530
1762
|
"attachButton": "_5KEEsG_attachButton",
|
|
1531
|
-
"
|
|
1532
|
-
"
|
|
1533
|
-
"
|
|
1534
|
-
"
|
|
1535
|
-
"
|
|
1536
|
-
"
|
|
1537
|
-
"
|
|
1538
|
-
"
|
|
1539
|
-
"
|
|
1763
|
+
"userRow": "_5KEEsG_userRow",
|
|
1764
|
+
"todoBody": "_5KEEsG_todoBody",
|
|
1765
|
+
"toolBodyText": "_5KEEsG_toolBodyText",
|
|
1766
|
+
"pendingCard": "_5KEEsG_pendingCard",
|
|
1767
|
+
"parentStrip": "_5KEEsG_parentStrip",
|
|
1768
|
+
"toolLocations": "_5KEEsG_toolLocations",
|
|
1769
|
+
"actionGroup": "_5KEEsG_actionGroup",
|
|
1770
|
+
"headerSide": "_5KEEsG_headerSide",
|
|
1771
|
+
"attachImg": "_5KEEsG_attachImg",
|
|
1772
|
+
"attachRemove": "_5KEEsG_attachRemove",
|
|
1773
|
+
"assistantRow": "_5KEEsG_assistantRow",
|
|
1774
|
+
"pendingQuestion": "_5KEEsG_pendingQuestion",
|
|
1775
|
+
"writeNoticeClose": "_5KEEsG_writeNoticeClose",
|
|
1776
|
+
"toolBody": "_5KEEsG_toolBody",
|
|
1540
1777
|
"sentChip": "_5KEEsG_sentChip",
|
|
1541
|
-
"
|
|
1778
|
+
"pendingBar": "_5KEEsG_pendingBar",
|
|
1779
|
+
"rowActions": "_5KEEsG_rowActions",
|
|
1542
1780
|
"modelSelect": "_5KEEsG_modelSelect",
|
|
1543
|
-
"slashGroupTitle": "_5KEEsG_slashGroupTitle",
|
|
1544
|
-
"emptyTitle": "_5KEEsG_emptyTitle",
|
|
1545
|
-
"body": "_5KEEsG_body",
|
|
1546
|
-
"userBubble": "_5KEEsG_userBubble",
|
|
1547
|
-
"reflowButton": "_5KEEsG_reflowButton",
|
|
1548
|
-
"toolBodyText": "_5KEEsG_toolBodyText",
|
|
1549
|
-
"rowPreview": "_5KEEsG_rowPreview",
|
|
1550
1781
|
"attachThumb": "_5KEEsG_attachThumb",
|
|
1551
|
-
"
|
|
1552
|
-
"rowActions": "_5KEEsG_rowActions",
|
|
1553
|
-
"jumpBottom": "_5KEEsG_jumpBottom",
|
|
1554
|
-
"reasoning": "_5KEEsG_reasoning",
|
|
1555
|
-
"modelLabel": "_5KEEsG_modelLabel",
|
|
1556
|
-
"writeNoticeClose": "_5KEEsG_writeNoticeClose",
|
|
1557
|
-
"todoDot": "_5KEEsG_todoDot",
|
|
1558
|
-
"composerChips": "_5KEEsG_composerChips",
|
|
1559
|
-
"composer": "_5KEEsG_composer"
|
|
1782
|
+
"pendingQText": "_5KEEsG_pendingQText"
|
|
1560
1783
|
};
|
|
1561
1784
|
//#endregion
|
|
1562
1785
|
//#region src/client/chat/ToolCard.tsx
|
|
@@ -2762,6 +2985,342 @@ window.__ModuleLoader__.load({
|
|
|
2762
2985
|
}, "dsh-sidenote: toast host");
|
|
2763
2986
|
}
|
|
2764
2987
|
//#endregion
|
|
2988
|
+
//#region src/client/sidechat/pending.ts
|
|
2989
|
+
function adapt012(pending) {
|
|
2990
|
+
if (typeof pending !== "object" || pending === null) return [];
|
|
2991
|
+
const o = pending;
|
|
2992
|
+
if (o.kind === "approval" && typeof o.answer === "function") return [{
|
|
2993
|
+
kind: "approval",
|
|
2994
|
+
key: typeof o.key === "string" ? o.key : "approval",
|
|
2995
|
+
toolName: typeof o.toolName === "string" ? o.toolName : "",
|
|
2996
|
+
...typeof o.reason === "string" ? { reason: o.reason } : {},
|
|
2997
|
+
answer: (outcome) => o.answer.call(o, outcome)
|
|
2998
|
+
}];
|
|
2999
|
+
if ((o.kind === "question" || o.kind === "plan-review") && typeof o.answer === "function" && typeof o.cancel === "function") {
|
|
3000
|
+
const questions = normalizeQuestions(o.questions ?? o.payload?.questions);
|
|
3001
|
+
if (questions === void 0) return [];
|
|
3002
|
+
return [{
|
|
3003
|
+
kind: "question",
|
|
3004
|
+
key: typeof o.key === "string" ? o.key : "question",
|
|
3005
|
+
planReview: o.kind === "plan-review",
|
|
3006
|
+
questions,
|
|
3007
|
+
answer: (answers) => o.answer.call(o, { answers }),
|
|
3008
|
+
cancel: () => o.cancel.call(o)
|
|
3009
|
+
}];
|
|
3010
|
+
}
|
|
3011
|
+
return [];
|
|
3012
|
+
}
|
|
3013
|
+
function adapt011(pending) {
|
|
3014
|
+
const items = [];
|
|
3015
|
+
for (const raw of pending) {
|
|
3016
|
+
const w = raw;
|
|
3017
|
+
if (typeof w.respond !== "function") continue;
|
|
3018
|
+
const respond = w.respond;
|
|
3019
|
+
const sessionId = typeof w.sessionId === "string" ? w.sessionId : void 0;
|
|
3020
|
+
if (sessionId === void 0) continue;
|
|
3021
|
+
const payload = w.payload ?? {};
|
|
3022
|
+
const key = typeof w.key === "string" ? w.key : `pending:${items.length}`;
|
|
3023
|
+
if (w.kind === "approval") {
|
|
3024
|
+
const approvalId = payload.approvalId;
|
|
3025
|
+
if (typeof approvalId !== "string") continue;
|
|
3026
|
+
items.push({
|
|
3027
|
+
kind: "approval",
|
|
3028
|
+
key,
|
|
3029
|
+
toolName: typeof payload.toolName === "string" ? payload.toolName : "",
|
|
3030
|
+
...typeof payload.reason === "string" ? { reason: payload.reason } : {},
|
|
3031
|
+
answer: async (outcome) => {
|
|
3032
|
+
if ((await respond({
|
|
3033
|
+
ok: true,
|
|
3034
|
+
value: {
|
|
3035
|
+
sessionId,
|
|
3036
|
+
approvalId,
|
|
3037
|
+
outcome
|
|
3038
|
+
}
|
|
3039
|
+
})).accepted === false) throw new Error("approval response rejected (not pending)");
|
|
3040
|
+
}
|
|
3041
|
+
});
|
|
3042
|
+
} else if (w.kind === "question") {
|
|
3043
|
+
const questions = normalizeQuestions(payload.questions);
|
|
3044
|
+
if (questions === void 0) continue;
|
|
3045
|
+
items.push({
|
|
3046
|
+
kind: "question",
|
|
3047
|
+
key,
|
|
3048
|
+
planReview: false,
|
|
3049
|
+
questions,
|
|
3050
|
+
answer: async (answers) => {
|
|
3051
|
+
if ((await respond({
|
|
3052
|
+
ok: true,
|
|
3053
|
+
value: {
|
|
3054
|
+
sessionId,
|
|
3055
|
+
answer: { answers }
|
|
3056
|
+
}
|
|
3057
|
+
})).accepted === false) throw new Error("question response rejected (not pending)");
|
|
3058
|
+
},
|
|
3059
|
+
cancel: async () => {
|
|
3060
|
+
await respond({
|
|
3061
|
+
ok: false,
|
|
3062
|
+
error: {
|
|
3063
|
+
code: "cancelled",
|
|
3064
|
+
message: "the user closed this question request",
|
|
3065
|
+
details: {}
|
|
3066
|
+
}
|
|
3067
|
+
});
|
|
3068
|
+
}
|
|
3069
|
+
});
|
|
3070
|
+
}
|
|
3071
|
+
}
|
|
3072
|
+
return items;
|
|
3073
|
+
}
|
|
3074
|
+
/** questions 字段归一(选项 {label,description?} 与纯字符串两形都收)。 */
|
|
3075
|
+
function normalizeQuestions(raw) {
|
|
3076
|
+
if (!Array.isArray(raw)) return void 0;
|
|
3077
|
+
const out = [];
|
|
3078
|
+
for (const rawQ of raw) {
|
|
3079
|
+
if (typeof rawQ !== "object" || rawQ === null) return void 0;
|
|
3080
|
+
const q = rawQ;
|
|
3081
|
+
if (typeof q.question !== "string") return void 0;
|
|
3082
|
+
const options = [];
|
|
3083
|
+
if (Array.isArray(q.options)) for (const rawO of q.options) if (typeof rawO === "string") options.push({ label: rawO });
|
|
3084
|
+
else if (typeof rawO === "object" && rawO !== null && typeof rawO.label === "string") {
|
|
3085
|
+
const oo = rawO;
|
|
3086
|
+
options.push({
|
|
3087
|
+
label: oo.label,
|
|
3088
|
+
...typeof oo.description === "string" ? { description: oo.description } : {}
|
|
3089
|
+
});
|
|
3090
|
+
} else return void 0;
|
|
3091
|
+
out.push({
|
|
3092
|
+
id: typeof q.id === "string" ? q.id : `q${out.length}`,
|
|
3093
|
+
question: q.question,
|
|
3094
|
+
...typeof q.header === "string" ? { header: q.header } : {},
|
|
3095
|
+
...typeof q.detail === "string" ? { detail: q.detail } : {},
|
|
3096
|
+
options,
|
|
3097
|
+
multiSelect: q.multiSelect === true
|
|
3098
|
+
});
|
|
3099
|
+
}
|
|
3100
|
+
return out;
|
|
3101
|
+
}
|
|
3102
|
+
/**
|
|
3103
|
+
* 双版本探测链(chatSourceOf 同款纪律):0.1.2 uiSession.pendingInteractions
|
|
3104
|
+
* (getSnapshot() 是 Map 才认)优先;0.1.1 Session 快照 pending 数组回退;
|
|
3105
|
+
* 双缺席 undefined(面板回退 pendingBar 跳转)。
|
|
3106
|
+
*/
|
|
3107
|
+
function createPendingStore(ctx, session, childId) {
|
|
3108
|
+
try {
|
|
3109
|
+
const pim = (typeof ctx.get === "function" ? ctx.get("uiSession") : void 0)?.pendingInteractions;
|
|
3110
|
+
if (pim !== void 0 && typeof pim.subscribe === "function" && typeof pim.getSnapshot === "function") {
|
|
3111
|
+
const obs = pim;
|
|
3112
|
+
if (obs.getSnapshot() instanceof Map) {
|
|
3113
|
+
let cachedMap = null;
|
|
3114
|
+
let cachedItems = [];
|
|
3115
|
+
return {
|
|
3116
|
+
available: true,
|
|
3117
|
+
subscribe: (fn) => obs.subscribe(fn),
|
|
3118
|
+
getSnapshot: () => {
|
|
3119
|
+
const map = obs.getSnapshot();
|
|
3120
|
+
if (map === cachedMap) return cachedItems;
|
|
3121
|
+
cachedMap = map;
|
|
3122
|
+
cachedItems = map instanceof Map ? adapt012(map.get(childId)) : [];
|
|
3123
|
+
return cachedItems;
|
|
3124
|
+
}
|
|
3125
|
+
};
|
|
3126
|
+
}
|
|
3127
|
+
}
|
|
3128
|
+
} catch {}
|
|
3129
|
+
if (session === void 0) return void 0;
|
|
3130
|
+
try {
|
|
3131
|
+
const snap = session.getSnapshot();
|
|
3132
|
+
if (Array.isArray(snap?.pending)) {
|
|
3133
|
+
let cachedArr = null;
|
|
3134
|
+
let cachedItems = [];
|
|
3135
|
+
return {
|
|
3136
|
+
available: true,
|
|
3137
|
+
subscribe: (fn) => session.subscribe(fn),
|
|
3138
|
+
getSnapshot: () => {
|
|
3139
|
+
const arr = session.getSnapshot()?.pending;
|
|
3140
|
+
if (arr === cachedArr) return cachedItems;
|
|
3141
|
+
cachedArr = arr;
|
|
3142
|
+
cachedItems = Array.isArray(arr) ? adapt011(arr) : [];
|
|
3143
|
+
return cachedItems;
|
|
3144
|
+
}
|
|
3145
|
+
};
|
|
3146
|
+
}
|
|
3147
|
+
} catch {}
|
|
3148
|
+
}
|
|
3149
|
+
//#endregion
|
|
3150
|
+
//#region src/client/sidechat/PendingCard.tsx
|
|
3151
|
+
/**
|
|
3152
|
+
* R8 审批/提问答复卡(L2 视图):钉在 composer 上方(原 pendingBar 位置)。
|
|
3153
|
+
* 自绘 + primitives 图标(材质同源,不求像素级复刻宿主审批卡)。
|
|
3154
|
+
*
|
|
3155
|
+
* 竞答纪律:先答先得——点击后置 answered 本地态;answer 失败(已被主视图
|
|
3156
|
+
* 抢答/settle)catch 吞错并回退按钮态(宿主 `.catch(() => setAnswered(false))`
|
|
3157
|
+
* 同款);卡片消失由快照驱动(pending 项消失即卸载),UI 不自造状态机。
|
|
3158
|
+
*/
|
|
3159
|
+
function PendingCardList({ items }) {
|
|
3160
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: items.map((item) => item.kind === "approval" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ApprovalCard, { item }, item.key) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QuestionCard, { item }, item.key)) });
|
|
3161
|
+
}
|
|
3162
|
+
/** 审批卡:reason + 拒绝 / 允许一次。 */
|
|
3163
|
+
function ApprovalCard({ item }) {
|
|
3164
|
+
useLocaleTick();
|
|
3165
|
+
const [answered, setAnswered] = (0, react.useState)(false);
|
|
3166
|
+
const answer = (outcome) => {
|
|
3167
|
+
setAnswered(true);
|
|
3168
|
+
item.answer(outcome).catch(() => {
|
|
3169
|
+
setAnswered(false);
|
|
3170
|
+
});
|
|
3171
|
+
};
|
|
3172
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3173
|
+
className: sidechat_module_css_default.pendingCard,
|
|
3174
|
+
"data-kind": "approval",
|
|
3175
|
+
children: [
|
|
3176
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3177
|
+
className: sidechat_module_css_default.pendingHead,
|
|
3178
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutline16, { size: 14 }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3179
|
+
className: sidechat_module_css_default.pendingTitle,
|
|
3180
|
+
children: t("pendingApprovalTitle")
|
|
3181
|
+
})]
|
|
3182
|
+
}),
|
|
3183
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3184
|
+
className: sidechat_module_css_default.pendingDesc,
|
|
3185
|
+
children: t("pendingApprovalDesc", { name: item.toolName })
|
|
3186
|
+
}),
|
|
3187
|
+
item.reason !== void 0 && item.reason !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3188
|
+
className: sidechat_module_css_default.pendingReason,
|
|
3189
|
+
children: item.reason
|
|
3190
|
+
}),
|
|
3191
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3192
|
+
className: sidechat_module_css_default.pendingActions,
|
|
3193
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3194
|
+
type: "button",
|
|
3195
|
+
className: sidechat_module_css_default.pendingBtnGhost,
|
|
3196
|
+
disabled: answered,
|
|
3197
|
+
onClick: () => {
|
|
3198
|
+
answer("rejected");
|
|
3199
|
+
},
|
|
3200
|
+
children: t("pendingReject")
|
|
3201
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3202
|
+
type: "button",
|
|
3203
|
+
className: sidechat_module_css_default.pendingBtnPrimary,
|
|
3204
|
+
disabled: answered,
|
|
3205
|
+
onClick: () => {
|
|
3206
|
+
answer("allowed-once");
|
|
3207
|
+
},
|
|
3208
|
+
children: t("pendingAllowOnce")
|
|
3209
|
+
})]
|
|
3210
|
+
})
|
|
3211
|
+
]
|
|
3212
|
+
});
|
|
3213
|
+
}
|
|
3214
|
+
/** 提问卡:选项(单选即点即答语义并入整批提交)+ 自定义 + 整批提交/取消。 */
|
|
3215
|
+
function QuestionCard({ item }) {
|
|
3216
|
+
useLocaleTick();
|
|
3217
|
+
const [selections, setSelections] = (0, react.useState)(/* @__PURE__ */ new Map());
|
|
3218
|
+
const [customs, setCustoms] = (0, react.useState)(/* @__PURE__ */ new Map());
|
|
3219
|
+
const [answered, setAnswered] = (0, react.useState)(false);
|
|
3220
|
+
const toggle = (qid, label, multi) => {
|
|
3221
|
+
const next = new Map(selections);
|
|
3222
|
+
const cur = new Set(next.get(qid) ?? []);
|
|
3223
|
+
if (multi) {
|
|
3224
|
+
if (cur.has(label)) cur.delete(label);
|
|
3225
|
+
else cur.add(label);
|
|
3226
|
+
} else {
|
|
3227
|
+
cur.clear();
|
|
3228
|
+
cur.add(label);
|
|
3229
|
+
}
|
|
3230
|
+
next.set(qid, cur);
|
|
3231
|
+
setSelections(next);
|
|
3232
|
+
};
|
|
3233
|
+
const ready = item.questions.every((q) => (selections.get(q.id)?.size ?? 0) > 0 || (customs.get(q.id)?.trim() ?? "") !== "");
|
|
3234
|
+
const submit = () => {
|
|
3235
|
+
setAnswered(true);
|
|
3236
|
+
item.answer(item.questions.map((q) => ({
|
|
3237
|
+
id: q.id,
|
|
3238
|
+
selected: [...selections.get(q.id) ?? []],
|
|
3239
|
+
...(customs.get(q.id)?.trim() ?? "") !== "" ? { custom: customs.get(q.id).trim() } : {}
|
|
3240
|
+
}))).catch(() => {
|
|
3241
|
+
setAnswered(false);
|
|
3242
|
+
});
|
|
3243
|
+
};
|
|
3244
|
+
const cancel = () => {
|
|
3245
|
+
setAnswered(true);
|
|
3246
|
+
item.cancel().catch(() => {
|
|
3247
|
+
setAnswered(false);
|
|
3248
|
+
});
|
|
3249
|
+
};
|
|
3250
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3251
|
+
className: sidechat_module_css_default.pendingCard,
|
|
3252
|
+
"data-kind": "question",
|
|
3253
|
+
children: [
|
|
3254
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3255
|
+
className: sidechat_module_css_default.pendingHead,
|
|
3256
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconQuestionOutline14, { size: 14 }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3257
|
+
className: sidechat_module_css_default.pendingTitle,
|
|
3258
|
+
children: item.planReview ? t("pendingPlanReview") : t("pendingQuestionTitle")
|
|
3259
|
+
})]
|
|
3260
|
+
}),
|
|
3261
|
+
item.questions.map((q) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3262
|
+
className: sidechat_module_css_default.pendingQuestion,
|
|
3263
|
+
children: [
|
|
3264
|
+
q.header !== void 0 && q.header !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3265
|
+
className: sidechat_module_css_default.pendingQHeader,
|
|
3266
|
+
children: q.header
|
|
3267
|
+
}),
|
|
3268
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3269
|
+
className: sidechat_module_css_default.pendingQText,
|
|
3270
|
+
children: q.question
|
|
3271
|
+
}),
|
|
3272
|
+
q.detail !== void 0 && q.detail !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3273
|
+
className: sidechat_module_css_default.pendingReason,
|
|
3274
|
+
children: q.detail
|
|
3275
|
+
}),
|
|
3276
|
+
q.options.map((o) => {
|
|
3277
|
+
const active = selections.get(q.id)?.has(o.label) === true;
|
|
3278
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
3279
|
+
type: "button",
|
|
3280
|
+
className: active ? sidechat_module_css_default.pendingOptionActive : sidechat_module_css_default.pendingOption,
|
|
3281
|
+
disabled: answered,
|
|
3282
|
+
onClick: () => {
|
|
3283
|
+
toggle(q.id, o.label, q.multiSelect);
|
|
3284
|
+
},
|
|
3285
|
+
children: [o.label, o.description !== void 0 && o.description !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3286
|
+
className: sidechat_module_css_default.pendingOptionDesc,
|
|
3287
|
+
children: o.description
|
|
3288
|
+
})]
|
|
3289
|
+
}, o.label);
|
|
3290
|
+
}),
|
|
3291
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
3292
|
+
className: sidechat_module_css_default.pendingCustom,
|
|
3293
|
+
placeholder: t("pendingCustomPlaceholder"),
|
|
3294
|
+
disabled: answered,
|
|
3295
|
+
value: customs.get(q.id) ?? "",
|
|
3296
|
+
onChange: (event) => {
|
|
3297
|
+
const next = new Map(customs);
|
|
3298
|
+
next.set(q.id, event.target.value);
|
|
3299
|
+
setCustoms(next);
|
|
3300
|
+
}
|
|
3301
|
+
})
|
|
3302
|
+
]
|
|
3303
|
+
}, q.id)),
|
|
3304
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3305
|
+
className: sidechat_module_css_default.pendingActions,
|
|
3306
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3307
|
+
type: "button",
|
|
3308
|
+
className: sidechat_module_css_default.pendingBtnGhost,
|
|
3309
|
+
disabled: answered,
|
|
3310
|
+
onClick: cancel,
|
|
3311
|
+
children: t("pendingQuestionCancel")
|
|
3312
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3313
|
+
type: "button",
|
|
3314
|
+
className: sidechat_module_css_default.pendingBtnPrimary,
|
|
3315
|
+
disabled: answered || !ready,
|
|
3316
|
+
onClick: submit,
|
|
3317
|
+
children: t("pendingQuestionSubmit")
|
|
3318
|
+
})]
|
|
3319
|
+
})
|
|
3320
|
+
]
|
|
3321
|
+
});
|
|
3322
|
+
}
|
|
3323
|
+
//#endregion
|
|
2765
3324
|
//#region src/client/sidechat/SideChatPanel.tsx
|
|
2766
3325
|
/**
|
|
2767
3326
|
* 侧边聊天 Tab 面板(L2 薄视图):相位编排 + 消息流 + composer。
|
|
@@ -2778,6 +3337,8 @@ window.__ModuleLoader__.load({
|
|
|
2778
3337
|
* 否则消息流永远为空(client-runtime 只为 staged 会话开窗的已知偏差)。
|
|
2779
3338
|
*/
|
|
2780
3339
|
const NOOP_UNSUBSCRIBE = () => {};
|
|
3340
|
+
/** uSES 空快照常量(禁产新引用——`?? []` 字面量每次新数组会无限重渲)。 */
|
|
3341
|
+
const NO_PENDING = [];
|
|
2781
3342
|
/** D2 写型工具名(无 diff 卡时的名字兜底)。 */
|
|
2782
3343
|
const WRITE_TOOLS = /* @__PURE__ */ new Set([
|
|
2783
3344
|
"edit",
|
|
@@ -2838,6 +3399,12 @@ window.__ModuleLoader__.load({
|
|
|
2838
3399
|
const fold = (0, react.useMemo)(() => createFoldStore(childId === void 0 ? void 0 : `dsh-sidenote:fold:v1:${childId}`), [childId]);
|
|
2839
3400
|
const parentSession = meta.parentSessionId === void 0 ? void 0 : ctx.sessions.binding(meta.parentSessionId)?.session;
|
|
2840
3401
|
const parentSnap = (0, react.useSyncExternalStore)((0, react.useCallback)((notify) => visible && parentSession !== void 0 ? parentSession.subscribe(notify) : NOOP_UNSUBSCRIBE, [visible, parentSession]), () => parentSession === void 0 ? null : parentSession.getSnapshot());
|
|
3402
|
+
const pendingStore = (0, react.useMemo)(() => childId === void 0 || session === void 0 ? void 0 : createPendingStore(ctx, session, childId), [
|
|
3403
|
+
ctx,
|
|
3404
|
+
session,
|
|
3405
|
+
childId
|
|
3406
|
+
]);
|
|
3407
|
+
const pendingItems = (0, react.useSyncExternalStore)((0, react.useCallback)((notify) => visible && pendingStore !== void 0 ? pendingStore.subscribe(notify) : NOOP_UNSUBSCRIBE, [visible, pendingStore]), () => pendingStore?.getSnapshot() ?? NO_PENDING);
|
|
2841
3408
|
const [writeNoticeDismissed, setWriteNoticeDismissed] = (0, react.useState)(() => typeof localStorage !== "undefined" && localStorage.getItem(WRITE_NOTICE_KEY) === "1");
|
|
2842
3409
|
const composer = useComposer(ctx, session, childId);
|
|
2843
3410
|
const [modelName, setModelName] = (0, react.useState)(null);
|
|
@@ -3011,7 +3578,8 @@ window.__ModuleLoader__.load({
|
|
|
3011
3578
|
children: "×"
|
|
3012
3579
|
})]
|
|
3013
3580
|
}),
|
|
3014
|
-
|
|
3581
|
+
pendingStore !== void 0 && pendingItems.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PendingCardList, { items: pendingItems }),
|
|
3582
|
+
pendingStore === void 0 && pendingCount > 0 && childId !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3015
3583
|
type: "button",
|
|
3016
3584
|
className: sidechat_module_css_default.pendingBar,
|
|
3017
3585
|
onClick: () => {
|
|
@@ -3250,6 +3818,66 @@ window.__ModuleLoader__.load({
|
|
|
3250
3818
|
}
|
|
3251
3819
|
}
|
|
3252
3820
|
//#endregion
|
|
3821
|
+
//#region src/client/sidechat/notify.ts
|
|
3822
|
+
/** 挂接保护窗:watcher 建立后该窗口内的翻转不视为「一个真实 turn 跑完」。 */
|
|
3823
|
+
const ATTACH_GRACE_MS = 800;
|
|
3824
|
+
/**
|
|
3825
|
+
* 翻转侦测核心(抽出来纯可测):running true→false 且距挂接超过保护窗
|
|
3826
|
+
* 时返回 true。调用方持状态。
|
|
3827
|
+
*/
|
|
3828
|
+
function shouldNotify(wasRunning, running, attachedAt, now) {
|
|
3829
|
+
return wasRunning && !running && now - attachedAt > ATTACH_GRACE_MS;
|
|
3830
|
+
}
|
|
3831
|
+
function registerCompletionNotify(ctx) {
|
|
3832
|
+
ctx.effect(() => {
|
|
3833
|
+
const watchers = /* @__PURE__ */ new Map();
|
|
3834
|
+
const rescan = () => {
|
|
3835
|
+
let tabs = [];
|
|
3836
|
+
try {
|
|
3837
|
+
tabs = collectSideTabs(ctx.betterSidebar.getSnapshot());
|
|
3838
|
+
} catch {
|
|
3839
|
+
return;
|
|
3840
|
+
}
|
|
3841
|
+
const alive = /* @__PURE__ */ new Set();
|
|
3842
|
+
for (const tab of tabs) {
|
|
3843
|
+
const childId = parseSideChatMeta(tab.meta).childId;
|
|
3844
|
+
if (childId === void 0) continue;
|
|
3845
|
+
alive.add(childId);
|
|
3846
|
+
if (watchers.has(childId)) continue;
|
|
3847
|
+
try {
|
|
3848
|
+
const session = ctx.sessions.binding(childId)?.session;
|
|
3849
|
+
if (session === void 0) continue;
|
|
3850
|
+
openSessionWindow(session);
|
|
3851
|
+
const title = tab.title;
|
|
3852
|
+
const watcher = {
|
|
3853
|
+
unsub: () => {},
|
|
3854
|
+
wasRunning: false,
|
|
3855
|
+
since: Date.now()
|
|
3856
|
+
};
|
|
3857
|
+
watcher.unsub = session.subscribe(() => {
|
|
3858
|
+
const running = session.getSnapshot()?.running === true;
|
|
3859
|
+
if (shouldNotify(watcher.wasRunning, running, watcher.since, Date.now())) showToast(t("sideChatDone", { title }));
|
|
3860
|
+
watcher.wasRunning = running;
|
|
3861
|
+
});
|
|
3862
|
+
watcher.wasRunning = session.getSnapshot()?.running === true;
|
|
3863
|
+
watchers.set(childId, watcher);
|
|
3864
|
+
} catch {}
|
|
3865
|
+
}
|
|
3866
|
+
for (const [id, w] of watchers) if (!alive.has(id)) {
|
|
3867
|
+
w.unsub();
|
|
3868
|
+
watchers.delete(id);
|
|
3869
|
+
}
|
|
3870
|
+
};
|
|
3871
|
+
const offState = ctx.betterSidebar.subscribeState(rescan);
|
|
3872
|
+
rescan();
|
|
3873
|
+
return () => {
|
|
3874
|
+
offState();
|
|
3875
|
+
for (const w of watchers.values()) w.unsub();
|
|
3876
|
+
watchers.clear();
|
|
3877
|
+
};
|
|
3878
|
+
}, "dsh-sidenote: completion notify");
|
|
3879
|
+
}
|
|
3880
|
+
//#endregion
|
|
3253
3881
|
//#region src/client/sidechat/index.tsx
|
|
3254
3882
|
/**
|
|
3255
3883
|
* Workitem 01 — 侧边聊天面板。
|
|
@@ -3308,6 +3936,7 @@ window.__ModuleLoader__.load({
|
|
|
3308
3936
|
registerSideChatReferenceSource(ctx);
|
|
3309
3937
|
registerHeaderEntry(ctx);
|
|
3310
3938
|
registerToastHost(ctx);
|
|
3939
|
+
registerCompletionNotify(ctx);
|
|
3311
3940
|
}
|
|
3312
3941
|
//#endregion
|
|
3313
3942
|
//#region src/client/annotate/model.ts
|
|
@@ -3760,43 +4389,43 @@ window.__ModuleLoader__.load({
|
|
|
3760
4389
|
document.head.appendChild(tag);
|
|
3761
4390
|
}
|
|
3762
4391
|
var annotate_module_css_default = {
|
|
3763
|
-
"cancelButton": "_SVViG_cancelButton",
|
|
3764
|
-
"editorNew": "_SVViG_editorNew",
|
|
3765
|
-
"editorFooter": "_SVViG_editorFooter",
|
|
3766
|
-
"confirmButton": "_SVViG_confirmButton",
|
|
3767
|
-
"chipClearAll": "_SVViG_chipClearAll",
|
|
3768
|
-
"editorTarget": "_SVViG_editorTarget",
|
|
3769
|
-
"chipNumber": "_SVViG_chipNumber",
|
|
3770
|
-
"chipText": "_SVViG_chipText",
|
|
3771
|
-
"editorAskRow": "_SVViG_editorAskRow",
|
|
3772
|
-
"chipWrap": "_SVViG_chipWrap",
|
|
3773
|
-
"chip": "_SVViG_chip",
|
|
3774
|
-
"highlight": "_SVViG_highlight",
|
|
3775
4392
|
"toolbarButton": "_SVViG_toolbarButton",
|
|
3776
|
-
"
|
|
3777
|
-
"chipPanel": "_SVViG_chipPanel",
|
|
3778
|
-
"editorInput": "_SVViG_editorInput",
|
|
3779
|
-
"hint": "_SVViG_hint",
|
|
3780
|
-
"toolbar": "_SVViG_toolbar",
|
|
3781
|
-
"saveButton": "_SVViG_saveButton",
|
|
4393
|
+
"editorSpacer": "_SVViG_editorSpacer",
|
|
3782
4394
|
"sentCardTitle": "_SVViG_sentCardTitle",
|
|
3783
|
-
"sentCardNote": "_SVViG_sentCardNote",
|
|
3784
|
-
"deleteButton": "_SVViG_deleteButton",
|
|
3785
4395
|
"chipRemove": "_SVViG_chipRemove",
|
|
3786
|
-
"editorAsk": "_SVViG_editorAsk",
|
|
3787
|
-
"hintClose": "_SVViG_hintClose",
|
|
3788
4396
|
"toolbarBelow": "_SVViG_toolbarBelow",
|
|
3789
|
-
"sentChipRow": "_SVViG_sentChipRow",
|
|
3790
|
-
"sentChip": "_SVViG_sentChip",
|
|
3791
4397
|
"editorTextarea": "_SVViG_editorTextarea",
|
|
4398
|
+
"chipWrap": "_SVViG_chipWrap",
|
|
4399
|
+
"chipClearAll": "_SVViG_chipClearAll",
|
|
4400
|
+
"editorNew": "_SVViG_editorNew",
|
|
4401
|
+
"badge": "_SVViG_badge",
|
|
4402
|
+
"editorAskRow": "_SVViG_editorAskRow",
|
|
4403
|
+
"chipText": "_SVViG_chipText",
|
|
3792
4404
|
"badgeSent": "_SVViG_badgeSent",
|
|
4405
|
+
"editorError": "_SVViG_editorError",
|
|
4406
|
+
"cancelButton": "_SVViG_cancelButton",
|
|
4407
|
+
"deleteButton": "_SVViG_deleteButton",
|
|
4408
|
+
"chipPanel": "_SVViG_chipPanel",
|
|
4409
|
+
"chipNote": "_SVViG_chipNote",
|
|
4410
|
+
"highlight": "_SVViG_highlight",
|
|
4411
|
+
"dshSidenoteHintIn": "_SVViG_dshSidenoteHintIn",
|
|
4412
|
+
"sentChipRow": "_SVViG_sentChipRow",
|
|
4413
|
+
"hintClose": "_SVViG_hintClose",
|
|
4414
|
+
"chipNumber": "_SVViG_chipNumber",
|
|
4415
|
+
"saveButton": "_SVViG_saveButton",
|
|
4416
|
+
"chip": "_SVViG_chip",
|
|
4417
|
+
"chipRow": "_SVViG_chipRow",
|
|
4418
|
+
"sentChip": "_SVViG_sentChip",
|
|
3793
4419
|
"sentCardQuote": "_SVViG_sentCardQuote",
|
|
4420
|
+
"hint": "_SVViG_hint",
|
|
4421
|
+
"editorInput": "_SVViG_editorInput",
|
|
4422
|
+
"toolbar": "_SVViG_toolbar",
|
|
4423
|
+
"confirmButton": "_SVViG_confirmButton",
|
|
3794
4424
|
"editorEdit": "_SVViG_editorEdit",
|
|
3795
|
-
"
|
|
3796
|
-
"
|
|
3797
|
-
"
|
|
3798
|
-
"
|
|
3799
|
-
"badge": "_SVViG_badge"
|
|
4425
|
+
"editorAsk": "_SVViG_editorAsk",
|
|
4426
|
+
"editorTarget": "_SVViG_editorTarget",
|
|
4427
|
+
"sentCardNote": "_SVViG_sentCardNote",
|
|
4428
|
+
"editorFooter": "_SVViG_editorFooter"
|
|
3800
4429
|
};
|
|
3801
4430
|
//#endregion
|
|
3802
4431
|
//#region src/client/annotate/hint.tsx
|