@yushaw/sanqian-chat 0.2.42 → 0.2.44
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/dist/core/index.d.mts +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/main/index.d.mts +1 -0
- package/dist/main/index.d.ts +1 -0
- package/dist/preload/factories.d.mts +1 -0
- package/dist/preload/factories.d.ts +1 -0
- package/dist/renderer/index.d.mts +2 -0
- package/dist/renderer/index.d.ts +2 -0
- package/dist/renderer/index.js +208 -35
- package/dist/renderer/index.mjs +208 -35
- package/package.json +2 -1
- package/src/renderer/styles/chat.css +53 -15
- package/src/renderer/styles/coreCss.ts +53 -15
- package/src/renderer/styles/safe.css +53 -15
package/dist/core/index.d.mts
CHANGED
package/dist/core/index.d.ts
CHANGED
package/dist/main/index.d.mts
CHANGED
package/dist/main/index.d.ts
CHANGED
|
@@ -67,6 +67,7 @@ interface ChatUiStrings {
|
|
|
67
67
|
embedWindow: string;
|
|
68
68
|
collapseSidebar: string;
|
|
69
69
|
history: string;
|
|
70
|
+
related: string;
|
|
70
71
|
remove: string;
|
|
71
72
|
}
|
|
72
73
|
type ChatThemeMode = 'light' | 'dark' | 'auto';
|
|
@@ -1259,6 +1260,7 @@ interface HistoryListProps {
|
|
|
1259
1260
|
today?: string;
|
|
1260
1261
|
yesterday?: string;
|
|
1261
1262
|
delete?: string;
|
|
1263
|
+
related?: string;
|
|
1262
1264
|
};
|
|
1263
1265
|
/** Whether a conversation should be highlighted (host-defined relation) */
|
|
1264
1266
|
isConversationHighlighted?: (conversation: ConversationInfo) => boolean;
|
package/dist/renderer/index.d.ts
CHANGED
|
@@ -67,6 +67,7 @@ interface ChatUiStrings {
|
|
|
67
67
|
embedWindow: string;
|
|
68
68
|
collapseSidebar: string;
|
|
69
69
|
history: string;
|
|
70
|
+
related: string;
|
|
70
71
|
remove: string;
|
|
71
72
|
}
|
|
72
73
|
type ChatThemeMode = 'light' | 'dark' | 'auto';
|
|
@@ -1259,6 +1260,7 @@ interface HistoryListProps {
|
|
|
1259
1260
|
today?: string;
|
|
1260
1261
|
yesterday?: string;
|
|
1261
1262
|
delete?: string;
|
|
1263
|
+
related?: string;
|
|
1262
1264
|
};
|
|
1263
1265
|
/** Whether a conversation should be highlighted (host-defined relation) */
|
|
1264
1266
|
isConversationHighlighted?: (conversation: ConversationInfo) => boolean;
|
package/dist/renderer/index.js
CHANGED
|
@@ -90,6 +90,7 @@ module.exports = __toCommonJS(renderer_exports);
|
|
|
90
90
|
var import_react = require("react");
|
|
91
91
|
var TYPEWRITER_DELAYS = { VERY_FAST: 2, FAST: 5, NORMAL: 10, SLOW: 20 };
|
|
92
92
|
var TYPEWRITER_THRESHOLDS = { VERY_FAST: 100, FAST: 50, NORMAL: 20 };
|
|
93
|
+
var MAX_DETACHED_SNAPSHOTS = 30;
|
|
93
94
|
var findToolCallIndex = (toolCalls, toolId, toolName) => {
|
|
94
95
|
if (!toolCalls || toolCalls.length === 0) return -1;
|
|
95
96
|
if (toolId) {
|
|
@@ -107,6 +108,34 @@ var findLastBlock = (blocks, predicate) => {
|
|
|
107
108
|
}
|
|
108
109
|
return void 0;
|
|
109
110
|
};
|
|
111
|
+
function cloneBlocks(blocks) {
|
|
112
|
+
return blocks?.map((block) => ({
|
|
113
|
+
...block,
|
|
114
|
+
toolArgs: block.toolArgs ? { ...block.toolArgs } : block.toolArgs
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
117
|
+
function cloneMessages(messages) {
|
|
118
|
+
return messages.map((message) => ({
|
|
119
|
+
...message,
|
|
120
|
+
toolCalls: message.toolCalls?.map((toolCall) => ({
|
|
121
|
+
...toolCall,
|
|
122
|
+
args: toolCall.args ? { ...toolCall.args } : toolCall.args
|
|
123
|
+
})),
|
|
124
|
+
blocks: cloneBlocks(message.blocks),
|
|
125
|
+
filePaths: message.filePaths ? [...message.filePaths] : message.filePaths,
|
|
126
|
+
attachedResources: message.attachedResources?.map((resource) => ({ ...resource }))
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
function normalizeConversationMessages(messages) {
|
|
130
|
+
return messages.filter((message) => message.role !== "tool").map((message) => ({
|
|
131
|
+
...message,
|
|
132
|
+
isStreaming: false,
|
|
133
|
+
isComplete: true
|
|
134
|
+
}));
|
|
135
|
+
}
|
|
136
|
+
function delay(ms) {
|
|
137
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
138
|
+
}
|
|
110
139
|
var CHAT_CAPABILITIES = {
|
|
111
140
|
conversationSwitch: {
|
|
112
141
|
supportsCancelActiveStream: true,
|
|
@@ -127,6 +156,7 @@ function useChat(options) {
|
|
|
127
156
|
const isMountedRef = (0, import_react.useRef)(true);
|
|
128
157
|
const messagesRef = (0, import_react.useRef)(messages);
|
|
129
158
|
const conversationIdRef = (0, import_react.useRef)(conversationId);
|
|
159
|
+
const detachedConversationSnapshotsRef = (0, import_react.useRef)(/* @__PURE__ */ new Map());
|
|
130
160
|
const currentRunIdRef = (0, import_react.useRef)(null);
|
|
131
161
|
const pendingInterruptStreamIdRef = (0, import_react.useRef)(null);
|
|
132
162
|
const currentAgentIdRef = (0, import_react.useRef)(null);
|
|
@@ -221,11 +251,49 @@ function useChat(options) {
|
|
|
221
251
|
pendingCancelRef.current = false;
|
|
222
252
|
pendingCancelFnRef.current = null;
|
|
223
253
|
}, []);
|
|
254
|
+
const setDetachedConversationSnapshot = (0, import_react.useCallback)((id, snapshot) => {
|
|
255
|
+
if (!id || snapshot.length === 0) return;
|
|
256
|
+
const map = detachedConversationSnapshotsRef.current;
|
|
257
|
+
if (map.has(id)) {
|
|
258
|
+
map.delete(id);
|
|
259
|
+
}
|
|
260
|
+
map.set(id, cloneMessages(snapshot));
|
|
261
|
+
while (map.size > MAX_DETACHED_SNAPSHOTS) {
|
|
262
|
+
const oldestKey = map.keys().next().value;
|
|
263
|
+
if (!oldestKey) break;
|
|
264
|
+
map.delete(oldestKey);
|
|
265
|
+
}
|
|
266
|
+
}, []);
|
|
224
267
|
const detachActiveStream = (0, import_react.useCallback)((detachContext) => {
|
|
225
268
|
const context = activeStreamContextRef.current;
|
|
226
269
|
if (!context || context.detached) {
|
|
227
270
|
return;
|
|
228
271
|
}
|
|
272
|
+
const detachedSnapshot = cloneMessages(normalizeConversationMessages(messagesRef.current));
|
|
273
|
+
const detachedAssistantMessageIndex = detachedSnapshot.findIndex(
|
|
274
|
+
(message) => message.id === context.assistantMessageId
|
|
275
|
+
);
|
|
276
|
+
if (detachedAssistantMessageIndex !== -1) {
|
|
277
|
+
const detachedAssistantMessage = detachedSnapshot[detachedAssistantMessageIndex];
|
|
278
|
+
const detachedContent = fullContentRef.current || displayedContentRef.current || detachedAssistantMessage.content;
|
|
279
|
+
detachedSnapshot[detachedAssistantMessageIndex] = {
|
|
280
|
+
...detachedAssistantMessage,
|
|
281
|
+
content: detachedContent,
|
|
282
|
+
finalContent: detachedContent || detachedAssistantMessage.finalContent,
|
|
283
|
+
blocks: currentBlocksRef.current.length > 0 ? cloneBlocks(currentBlocksRef.current) : detachedAssistantMessage.blocks,
|
|
284
|
+
thinking: detachedAssistantMessage.thinking?.trimEnd(),
|
|
285
|
+
currentThinking: void 0,
|
|
286
|
+
isStreaming: false,
|
|
287
|
+
isThinkingStreaming: false,
|
|
288
|
+
isThinkingPaused: false,
|
|
289
|
+
isToolCallsStreaming: false,
|
|
290
|
+
isComplete: true
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
if (detachedSnapshot.length > 0) {
|
|
294
|
+
context.detachedSnapshot = detachedSnapshot;
|
|
295
|
+
setDetachedConversationSnapshot(context.conversationId, detachedSnapshot);
|
|
296
|
+
}
|
|
229
297
|
context.detached = true;
|
|
230
298
|
context.detachContext = detachContext;
|
|
231
299
|
if (typewriterIntervalRef.current) {
|
|
@@ -241,19 +309,72 @@ function useChat(options) {
|
|
|
241
309
|
pendingInterruptStreamIdRef.current = null;
|
|
242
310
|
clearPendingCancel();
|
|
243
311
|
suppressStreamRef.current = false;
|
|
244
|
-
}, [clearPendingCancel, resetStreamBuffers]);
|
|
312
|
+
}, [clearPendingCancel, resetStreamBuffers, setDetachedConversationSnapshot]);
|
|
313
|
+
const refreshConversationIfVisible = (0, import_react.useCallback)(async (id) => {
|
|
314
|
+
if (!id || conversationIdRef.current !== id) return false;
|
|
315
|
+
try {
|
|
316
|
+
const detail = await adapter.getConversation(id);
|
|
317
|
+
if (!isMountedRef.current || conversationIdRef.current !== id) return false;
|
|
318
|
+
const normalizedMessages = normalizeConversationMessages(detail.messages);
|
|
319
|
+
if (normalizedMessages.length === 0) return false;
|
|
320
|
+
detachedConversationSnapshotsRef.current.delete(id);
|
|
321
|
+
setMessages(normalizedMessages);
|
|
322
|
+
setConversationTitle(detail.title ?? null);
|
|
323
|
+
return true;
|
|
324
|
+
} catch (refreshError) {
|
|
325
|
+
console.warn("[useChat] Failed to refresh conversation after detached stream completion:", refreshError);
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
}, [adapter]);
|
|
329
|
+
const refreshConversationIfVisibleWithRetry = (0, import_react.useCallback)((id, retryDelaysMs) => {
|
|
330
|
+
if (!id) return;
|
|
331
|
+
void (async () => {
|
|
332
|
+
for (const retryDelayMs of retryDelaysMs) {
|
|
333
|
+
if (retryDelayMs > 0) {
|
|
334
|
+
await delay(retryDelayMs);
|
|
335
|
+
}
|
|
336
|
+
if (!isMountedRef.current || conversationIdRef.current !== id) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
const refreshed = await refreshConversationIfVisible(id);
|
|
340
|
+
if (refreshed) {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
})();
|
|
345
|
+
}, [refreshConversationIfVisible]);
|
|
245
346
|
const handleStreamEvent = (0, import_react.useCallback)((event, streamContext) => {
|
|
246
347
|
if (!isMountedRef.current) return;
|
|
247
348
|
const isActiveStream = activeStreamContextRef.current?.token === streamContext.token && !streamContext.detached;
|
|
248
349
|
if (!isActiveStream) {
|
|
249
350
|
if (event.type === "done" && event.conversationId && !streamContext.didReportConversationChange) {
|
|
351
|
+
if (streamContext.conversationId && streamContext.conversationId !== event.conversationId) {
|
|
352
|
+
detachedConversationSnapshotsRef.current.delete(streamContext.conversationId);
|
|
353
|
+
}
|
|
354
|
+
streamContext.conversationId = event.conversationId;
|
|
250
355
|
streamContext.didReportConversationChange = true;
|
|
356
|
+
if (streamContext.detachedSnapshot?.length) {
|
|
357
|
+
setDetachedConversationSnapshot(event.conversationId, streamContext.detachedSnapshot);
|
|
358
|
+
}
|
|
251
359
|
onConversationChange?.(event.conversationId, event.title, {
|
|
252
360
|
source: "background",
|
|
253
361
|
streamToken: streamContext.token,
|
|
254
362
|
detached: true,
|
|
255
363
|
detachContext: streamContext.detachContext
|
|
256
364
|
});
|
|
365
|
+
refreshConversationIfVisibleWithRetry(event.conversationId, [0, 300, 900]);
|
|
366
|
+
} else if (event.type === "done" && event.conversationId && streamContext.didReportConversationChange) {
|
|
367
|
+
if (streamContext.detachedSnapshot?.length) {
|
|
368
|
+
setDetachedConversationSnapshot(event.conversationId, streamContext.detachedSnapshot);
|
|
369
|
+
}
|
|
370
|
+
refreshConversationIfVisibleWithRetry(event.conversationId, [0, 300, 900]);
|
|
371
|
+
}
|
|
372
|
+
const isTerminalEvent = event.type === "done" || event.type === "cancelled" || event.type === "error";
|
|
373
|
+
if (isTerminalEvent) {
|
|
374
|
+
streamContext.detachedSnapshot = void 0;
|
|
375
|
+
}
|
|
376
|
+
if (isTerminalEvent && activeStreamContextRef.current?.token === streamContext.token) {
|
|
377
|
+
activeStreamContextRef.current = null;
|
|
257
378
|
}
|
|
258
379
|
return;
|
|
259
380
|
}
|
|
@@ -338,9 +459,9 @@ function useChat(options) {
|
|
|
338
459
|
return updated;
|
|
339
460
|
});
|
|
340
461
|
const qLen = tokenQueueRef.current.length;
|
|
341
|
-
const
|
|
462
|
+
const delay2 = qLen > TYPEWRITER_THRESHOLDS.VERY_FAST ? TYPEWRITER_DELAYS.VERY_FAST : qLen > TYPEWRITER_THRESHOLDS.FAST ? TYPEWRITER_DELAYS.FAST : qLen > TYPEWRITER_THRESHOLDS.NORMAL ? TYPEWRITER_DELAYS.NORMAL : TYPEWRITER_DELAYS.SLOW;
|
|
342
463
|
if (typewriterIntervalRef.current !== null) {
|
|
343
|
-
typewriterIntervalRef.current = setTimeout(tick,
|
|
464
|
+
typewriterIntervalRef.current = setTimeout(tick, delay2);
|
|
344
465
|
}
|
|
345
466
|
} else {
|
|
346
467
|
typewriterIntervalRef.current = null;
|
|
@@ -603,6 +724,7 @@ function useChat(options) {
|
|
|
603
724
|
});
|
|
604
725
|
resetStreamBuffers();
|
|
605
726
|
if (event.conversationId) {
|
|
727
|
+
streamContext.conversationId = event.conversationId;
|
|
606
728
|
streamContext.didReportConversationChange = true;
|
|
607
729
|
setConversationId(event.conversationId);
|
|
608
730
|
onConversationChange?.(event.conversationId, event.title, {
|
|
@@ -703,7 +825,7 @@ function useChat(options) {
|
|
|
703
825
|
break;
|
|
704
826
|
}
|
|
705
827
|
}
|
|
706
|
-
}, [clearPendingCancel, flushTypewriter, onConversationChange, onError, resetStreamBuffers]);
|
|
828
|
+
}, [clearPendingCancel, flushTypewriter, onConversationChange, onError, refreshConversationIfVisibleWithRetry, resetStreamBuffers, setDetachedConversationSnapshot]);
|
|
707
829
|
const trySendMessage = (0, import_react.useCallback)(async (content, sendOptions) => {
|
|
708
830
|
const trimmedContent = content.trim();
|
|
709
831
|
const hasAttachedResources = (sendOptions?.attachedResources?.length ?? 0) > 0;
|
|
@@ -739,6 +861,7 @@ function useChat(options) {
|
|
|
739
861
|
const streamContext = {
|
|
740
862
|
token: crypto.randomUUID(),
|
|
741
863
|
assistantMessageId: assistantMessage.id,
|
|
864
|
+
conversationId: conversationIdRef.current,
|
|
742
865
|
detached: false,
|
|
743
866
|
didReportConversationChange: false
|
|
744
867
|
};
|
|
@@ -861,6 +984,7 @@ function useChat(options) {
|
|
|
861
984
|
activeStreamContextRef.current = null;
|
|
862
985
|
clearPendingCancel();
|
|
863
986
|
suppressStreamRef.current = false;
|
|
987
|
+
detachedConversationSnapshotsRef.current.clear();
|
|
864
988
|
}, [clearPendingCancel, resetStreamBuffers]);
|
|
865
989
|
const loadConversation = (0, import_react.useCallback)(async (id, optionsArg) => {
|
|
866
990
|
const cancelActiveStream = optionsArg?.cancelActiveStream ?? true;
|
|
@@ -877,11 +1001,16 @@ function useChat(options) {
|
|
|
877
1001
|
setError(null);
|
|
878
1002
|
const detail = await adapter.getConversation(id);
|
|
879
1003
|
if (!isMountedRef.current) return;
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
1004
|
+
const normalizedMessages = normalizeConversationMessages(detail.messages);
|
|
1005
|
+
const detachedSnapshot = detachedConversationSnapshotsRef.current.get(id);
|
|
1006
|
+
const shouldUseDetachedSnapshot = normalizedMessages.length === 0 && !!detachedSnapshot?.length;
|
|
1007
|
+
const nextMessages = shouldUseDetachedSnapshot ? cloneMessages(detachedSnapshot) : normalizedMessages;
|
|
1008
|
+
if (!shouldUseDetachedSnapshot) {
|
|
1009
|
+
detachedConversationSnapshotsRef.current.delete(id);
|
|
1010
|
+
} else {
|
|
1011
|
+
refreshConversationIfVisibleWithRetry(id, [250, 800, 1800]);
|
|
1012
|
+
}
|
|
1013
|
+
setMessages(nextMessages);
|
|
885
1014
|
setConversationId(detail.id);
|
|
886
1015
|
setConversationTitle(detail.title);
|
|
887
1016
|
currentAgentIdRef.current = detail.agentId ?? currentAgentIdRef.current;
|
|
@@ -892,7 +1021,7 @@ function useChat(options) {
|
|
|
892
1021
|
} finally {
|
|
893
1022
|
if (isMountedRef.current) setIsLoading(false);
|
|
894
1023
|
}
|
|
895
|
-
}, [adapter, detachActiveStream, onError, stopStreaming]);
|
|
1024
|
+
}, [adapter, detachActiveStream, onError, refreshConversationIfVisibleWithRetry, stopStreaming]);
|
|
896
1025
|
const newConversation = (0, import_react.useCallback)((optionsArg) => {
|
|
897
1026
|
const cancelActiveStream = optionsArg?.cancelActiveStream ?? true;
|
|
898
1027
|
const activeStream = activeStreamContextRef.current;
|
|
@@ -1151,6 +1280,7 @@ var CHAT_UI_STRINGS = {
|
|
|
1151
1280
|
embedWindow: "Embed",
|
|
1152
1281
|
collapseSidebar: "Collapse",
|
|
1153
1282
|
history: "History",
|
|
1283
|
+
related: "RELATED",
|
|
1154
1284
|
// Resource
|
|
1155
1285
|
remove: "Remove"
|
|
1156
1286
|
},
|
|
@@ -1210,6 +1340,7 @@ var CHAT_UI_STRINGS = {
|
|
|
1210
1340
|
embedWindow: "\u5D4C\u5165",
|
|
1211
1341
|
collapseSidebar: "\u6536\u8D77",
|
|
1212
1342
|
history: "\u5386\u53F2",
|
|
1343
|
+
related: "\u76F8\u5173",
|
|
1213
1344
|
// Resource
|
|
1214
1345
|
remove: "\u79FB\u9664"
|
|
1215
1346
|
}
|
|
@@ -1361,13 +1492,13 @@ function useConnection(options) {
|
|
|
1361
1492
|
const isFirstAttempt = status === "disconnected" && reconnectAttemptsRef.current === 0;
|
|
1362
1493
|
const baseDelay = isFirstAttempt ? 0 : Math.min(500 * Math.pow(2, reconnectAttemptsRef.current), 5e3);
|
|
1363
1494
|
const jitter = isFirstAttempt ? 0 : Math.random() * 500;
|
|
1364
|
-
const
|
|
1495
|
+
const delay2 = baseDelay + jitter;
|
|
1365
1496
|
const timer = setTimeout(() => {
|
|
1366
1497
|
if (!isMountedRef.current) return;
|
|
1367
1498
|
reconnectAttemptsRef.current++;
|
|
1368
1499
|
adapter.connect().catch(() => {
|
|
1369
1500
|
});
|
|
1370
|
-
},
|
|
1501
|
+
}, delay2);
|
|
1371
1502
|
return () => clearTimeout(timer);
|
|
1372
1503
|
}, [status, autoConnect, adapter]);
|
|
1373
1504
|
(0, import_react4.useEffect)(() => {
|
|
@@ -1915,13 +2046,15 @@ code {
|
|
|
1915
2046
|
border-radius: 6px !important;
|
|
1916
2047
|
overflow: visible !important;
|
|
1917
2048
|
background: transparent !important;
|
|
1918
|
-
margin:
|
|
2049
|
+
margin: 4px 0 !important;
|
|
2050
|
+
padding: 0 !important;
|
|
2051
|
+
gap: 0 !important;
|
|
1919
2052
|
}
|
|
1920
2053
|
|
|
1921
2054
|
[data-streamdown="code-block-header"] {
|
|
1922
2055
|
position: absolute !important;
|
|
1923
|
-
top:
|
|
1924
|
-
left:
|
|
2056
|
+
top: 4px !important;
|
|
2057
|
+
left: 10px !important;
|
|
1925
2058
|
right: auto !important;
|
|
1926
2059
|
z-index: 10;
|
|
1927
2060
|
padding: 0 !important;
|
|
@@ -1934,8 +2067,8 @@ code {
|
|
|
1934
2067
|
|
|
1935
2068
|
[data-streamdown="code-block-actions"] {
|
|
1936
2069
|
position: absolute !important;
|
|
1937
|
-
top:
|
|
1938
|
-
right:
|
|
2070
|
+
top: 4px !important;
|
|
2071
|
+
right: 6px !important;
|
|
1939
2072
|
z-index: 11;
|
|
1940
2073
|
display: flex !important;
|
|
1941
2074
|
align-items: center;
|
|
@@ -1955,7 +2088,7 @@ code {
|
|
|
1955
2088
|
|
|
1956
2089
|
[data-streamdown="code-block-header"] > span:first-child {
|
|
1957
2090
|
display: inline-flex;
|
|
1958
|
-
font-size:
|
|
2091
|
+
font-size: 10px;
|
|
1959
2092
|
color: var(--color-muted);
|
|
1960
2093
|
text-transform: lowercase;
|
|
1961
2094
|
}
|
|
@@ -1970,7 +2103,7 @@ code {
|
|
|
1970
2103
|
/* Normalize action buttons for both streamdown v1 (header>div) and v2 (code-block-actions). */
|
|
1971
2104
|
[data-streamdown="code-block-header"] button,
|
|
1972
2105
|
[data-streamdown="code-block-actions"] button {
|
|
1973
|
-
padding:
|
|
2106
|
+
padding: 2px !important;
|
|
1974
2107
|
border: none !important;
|
|
1975
2108
|
border-radius: 4px !important;
|
|
1976
2109
|
background: var(--color-surface) !important;
|
|
@@ -1987,8 +2120,8 @@ code {
|
|
|
1987
2120
|
[data-streamdown="code-block-header"] svg,
|
|
1988
2121
|
[data-streamdown="code-block-actions"] svg {
|
|
1989
2122
|
color: var(--color-muted) !important;
|
|
1990
|
-
width:
|
|
1991
|
-
height:
|
|
2123
|
+
width: 11px !important;
|
|
2124
|
+
height: 11px !important;
|
|
1992
2125
|
}
|
|
1993
2126
|
|
|
1994
2127
|
[data-streamdown="code-block-header"] button:hover svg,
|
|
@@ -1997,18 +2130,33 @@ code {
|
|
|
1997
2130
|
}
|
|
1998
2131
|
|
|
1999
2132
|
[data-streamdown="code-block-body"] {
|
|
2000
|
-
padding:
|
|
2133
|
+
padding: 18px 12px 8px !important;
|
|
2001
2134
|
background: rgba(0, 0, 0, 0.02) !important;
|
|
2002
2135
|
border-radius: 6px !important;
|
|
2136
|
+
border: none !important;
|
|
2137
|
+
box-shadow: none !important;
|
|
2003
2138
|
font-size: 13px !important;
|
|
2004
2139
|
line-height: 1.5 !important;
|
|
2005
2140
|
white-space: pre !important;
|
|
2006
2141
|
overflow-x: auto !important;
|
|
2007
2142
|
}
|
|
2008
2143
|
|
|
2144
|
+
[data-streamdown="code-block-body"] pre {
|
|
2145
|
+
margin: 0 !important;
|
|
2146
|
+
padding: 0 !important;
|
|
2147
|
+
border: none !important;
|
|
2148
|
+
background: transparent !important;
|
|
2149
|
+
border-radius: 0 !important;
|
|
2150
|
+
}
|
|
2151
|
+
|
|
2009
2152
|
[data-streamdown="code-block-body"] code {
|
|
2010
2153
|
white-space: pre !important;
|
|
2011
2154
|
display: block !important;
|
|
2155
|
+
color: var(--color-text);
|
|
2156
|
+
}
|
|
2157
|
+
|
|
2158
|
+
[data-streamdown="code-block-body"] code > span {
|
|
2159
|
+
display: block;
|
|
2012
2160
|
}
|
|
2013
2161
|
|
|
2014
2162
|
.dark [data-streamdown="code-block-body"],
|
|
@@ -2022,17 +2170,38 @@ code {
|
|
|
2022
2170
|
|
|
2023
2171
|
[data-streamdown="code-block-body"],
|
|
2024
2172
|
[data-streamdown="code-block-body"] code {
|
|
2025
|
-
|
|
2026
|
-
opacity: 0.85;
|
|
2173
|
+
opacity: 1;
|
|
2027
2174
|
}
|
|
2028
2175
|
|
|
2029
2176
|
[data-streamdown="code-block-body"] code span[style] {
|
|
2030
2177
|
background-color: transparent !important;
|
|
2031
2178
|
}
|
|
2032
2179
|
|
|
2033
|
-
|
|
2034
|
-
:
|
|
2035
|
-
|
|
2180
|
+
[data-streamdown="code-block-body"] pre[style*="--sdm-bg"] {
|
|
2181
|
+
background-color: var(--sdm-bg) !important;
|
|
2182
|
+
}
|
|
2183
|
+
|
|
2184
|
+
.dark [data-streamdown="code-block-body"] pre[style*="--sdm-bg"],
|
|
2185
|
+
:root.dark [data-streamdown="code-block-body"] pre[style*="--sdm-bg"] {
|
|
2186
|
+
background-color: var(--shiki-dark-bg, var(--sdm-bg)) !important;
|
|
2187
|
+
}
|
|
2188
|
+
|
|
2189
|
+
[data-streamdown="code-block-body"] code span[style*="--sdm-c"] {
|
|
2190
|
+
color: var(--sdm-c) !important;
|
|
2191
|
+
}
|
|
2192
|
+
|
|
2193
|
+
.dark [data-streamdown="code-block-body"] code span[style*="--sdm-c"],
|
|
2194
|
+
:root.dark [data-streamdown="code-block-body"] code span[style*="--sdm-c"] {
|
|
2195
|
+
color: var(--shiki-dark, var(--sdm-c)) !important;
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
[data-streamdown="code-block-body"] code span[style*="--sdm-tbg"] {
|
|
2199
|
+
background-color: var(--sdm-tbg) !important;
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2202
|
+
.dark [data-streamdown="code-block-body"] code span[style*="--sdm-tbg"],
|
|
2203
|
+
:root.dark [data-streamdown="code-block-body"] code span[style*="--sdm-tbg"] {
|
|
2204
|
+
background-color: var(--shiki-dark-bg, var(--sdm-tbg)) !important;
|
|
2036
2205
|
}
|
|
2037
2206
|
|
|
2038
2207
|
[data-streamdown="table-wrapper"].my-4 {
|
|
@@ -7025,6 +7194,7 @@ var import_react21 = require("react");
|
|
|
7025
7194
|
// src/renderer/renderers/MarkdownRenderer.tsx
|
|
7026
7195
|
var import_react18 = require("react");
|
|
7027
7196
|
var import_streamdown = require("streamdown");
|
|
7197
|
+
var import_code = require("@streamdown/code");
|
|
7028
7198
|
var import_rehype_harden = require("rehype-harden");
|
|
7029
7199
|
var import_remark_gfm = __toESM(require("remark-gfm"));
|
|
7030
7200
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
@@ -7083,6 +7253,7 @@ var MarkdownRenderer = (0, import_react18.memo)(function MarkdownRenderer2({
|
|
|
7083
7253
|
const remarkPlugins = (0, import_react18.useMemo)(() => {
|
|
7084
7254
|
return [import_remark_gfm.default];
|
|
7085
7255
|
}, []);
|
|
7256
|
+
const streamdownPlugins = (0, import_react18.useMemo)(() => ({ code: import_code.code }), []);
|
|
7086
7257
|
const customComponents = (0, import_react18.useMemo)(() => {
|
|
7087
7258
|
const comps = {};
|
|
7088
7259
|
comps.p = ({ children }) => {
|
|
@@ -7135,6 +7306,7 @@ var MarkdownRenderer = (0, import_react18.memo)(function MarkdownRenderer2({
|
|
|
7135
7306
|
{
|
|
7136
7307
|
remarkPlugins,
|
|
7137
7308
|
rehypePlugins,
|
|
7309
|
+
plugins: streamdownPlugins,
|
|
7138
7310
|
components: customComponents,
|
|
7139
7311
|
mode: isStreaming ? "streaming" : "static",
|
|
7140
7312
|
isAnimating: isStreaming,
|
|
@@ -7870,7 +8042,7 @@ var SanqianChatMessage = (0, import_react21.memo)(function SanqianChatMessage2({
|
|
|
7870
8042
|
"div",
|
|
7871
8043
|
{
|
|
7872
8044
|
className: `message-bubble-wrapper ${isUser ? "rounded-2xl shadow-sm bg-[var(--chat-accent)] text-white px-4 py-3 whitespace-pre-wrap break-words" : "text-[var(--chat-text)] break-words"}`,
|
|
7873
|
-
children: isUser ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "whitespace-pre-wrap", children: message.content }) : message.content ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MarkdownRenderer, { content: message.content, isStreaming: message.isStreaming, className: "px-
|
|
8045
|
+
children: isUser ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "whitespace-pre-wrap", children: message.content }) : message.content ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MarkdownRenderer, { content: message.content, isStreaming: message.isStreaming, className: "px-0" }) : showStreamingPlaceholder ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-2 text-[var(--chat-muted)] italic min-h-[1.5rem]", children: [
|
|
7874
8046
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex gap-1 items-center", children: [
|
|
7875
8047
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "w-1.5 h-1.5 bg-[var(--chat-accent)] rounded-full animate-bounce", style: { animationDelay: "0ms" } }),
|
|
7876
8048
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "w-1.5 h-1.5 bg-[var(--chat-accent)] rounded-full animate-bounce", style: { animationDelay: "150ms" } }),
|
|
@@ -10073,7 +10245,7 @@ var FloatingChat = (0, import_react35.memo)(function FloatingChat2({
|
|
|
10073
10245
|
"div",
|
|
10074
10246
|
{
|
|
10075
10247
|
className: `message-bubble-wrapper ${isUser ? "rounded-2xl shadow-sm bg-[var(--chat-accent)] text-white px-4 py-3 whitespace-pre-wrap break-words" : "text-[var(--chat-text)] break-words"}`,
|
|
10076
|
-
children: isUser ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "whitespace-pre-wrap", children: message.content }) : message.content && (renderContent ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "prose prose-chat dark:prose-invert max-w-none px-
|
|
10248
|
+
children: isUser ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "whitespace-pre-wrap", children: message.content }) : message.content && (renderContent ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "prose prose-chat dark:prose-invert max-w-none px-0", children: renderContent(message.content, message.isStreaming ?? false) }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MarkdownRenderer, { content: message.content, isStreaming: message.isStreaming, className: "px-0" }))
|
|
10077
10249
|
}
|
|
10078
10250
|
) }) }) });
|
|
10079
10251
|
},
|
|
@@ -10311,7 +10483,7 @@ var HistoryList = (0, import_react36.memo)(function HistoryList2({
|
|
|
10311
10483
|
deleteText: "#ef4444",
|
|
10312
10484
|
loadingDot: isDarkMode ? "rgba(255, 255, 255, 0.3)" : "rgba(0, 0, 0, 0.2)"
|
|
10313
10485
|
};
|
|
10314
|
-
const loadingDots = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { display: "flex", justifyContent: "center", padding: "1.5rem 0" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { display: "flex", gap: "0.25rem" }, children: [0, 150, 300].map((
|
|
10486
|
+
const loadingDots = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { display: "flex", justifyContent: "center", padding: "1.5rem 0" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { display: "flex", gap: "0.25rem" }, children: [0, 150, 300].map((delay2) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
10315
10487
|
"span",
|
|
10316
10488
|
{
|
|
10317
10489
|
style: {
|
|
@@ -10320,10 +10492,10 @@ var HistoryList = (0, import_react36.memo)(function HistoryList2({
|
|
|
10320
10492
|
borderRadius: "50%",
|
|
10321
10493
|
background: colors.loadingDot,
|
|
10322
10494
|
animation: "bounce 1s infinite",
|
|
10323
|
-
animationDelay: `${
|
|
10495
|
+
animationDelay: `${delay2}ms`
|
|
10324
10496
|
}
|
|
10325
10497
|
},
|
|
10326
|
-
|
|
10498
|
+
delay2
|
|
10327
10499
|
)) }) });
|
|
10328
10500
|
if (isLoading && conversations.length === 0) {
|
|
10329
10501
|
return loadingDots;
|
|
@@ -10336,7 +10508,7 @@ var HistoryList = (0, import_react36.memo)(function HistoryList2({
|
|
|
10336
10508
|
const isSelected = conv.id === selectedId;
|
|
10337
10509
|
const isHovered = conv.id === hoveredId;
|
|
10338
10510
|
const isHighlighted = isConversationHighlighted?.(conv) === true;
|
|
10339
|
-
const resolvedHighlightLabel = isHighlighted ? (typeof highlightedLabel === "function" ? highlightedLabel(conv) : highlightedLabel) ?? "RELATED" : null;
|
|
10511
|
+
const resolvedHighlightLabel = isHighlighted ? (typeof highlightedLabel === "function" ? highlightedLabel(conv) : highlightedLabel) ?? strings.related ?? "RELATED" : null;
|
|
10340
10512
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
10341
10513
|
"div",
|
|
10342
10514
|
{
|
|
@@ -10987,7 +11159,7 @@ var CompactChat = (0, import_react38.memo)(function CompactChat2({
|
|
|
10987
11159
|
content: message.content,
|
|
10988
11160
|
isStreaming: message.isStreaming,
|
|
10989
11161
|
linkHandler,
|
|
10990
|
-
className: "px-
|
|
11162
|
+
className: "px-0"
|
|
10991
11163
|
}
|
|
10992
11164
|
)
|
|
10993
11165
|
}
|
|
@@ -11187,7 +11359,8 @@ var CompactChat = (0, import_react38.memo)(function CompactChat2({
|
|
|
11187
11359
|
loadMore: mergedStrings.loadMore,
|
|
11188
11360
|
today: mergedStrings.today,
|
|
11189
11361
|
yesterday: mergedStrings.yesterday,
|
|
11190
|
-
delete: mergedStrings.delete
|
|
11362
|
+
delete: mergedStrings.delete,
|
|
11363
|
+
related: mergedStrings.related
|
|
11191
11364
|
}
|
|
11192
11365
|
}
|
|
11193
11366
|
)
|