@nextclaw/ui 0.5.24 → 0.5.26
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/CHANGELOG.md +12 -0
- package/dist/assets/{ChannelsList-CAuBEcOr.js → ChannelsList-D0Wk08Ki.js} +1 -1
- package/dist/assets/ChatPage-Deg2lBH4.js +32 -0
- package/dist/assets/{CronConfig-jOEPCnpf.js → CronConfig-D-3Y8kWb.js} +1 -1
- package/dist/assets/{DocBrowser-wov_cBSN.js → DocBrowser-BSPKhqrK.js} +1 -1
- package/dist/assets/{MarketplacePage-Cob6DGoO.js → MarketplacePage-Dkm2FTtN.js} +1 -1
- package/dist/assets/{ModelConfig-C_Y3UDYr.js → ModelConfig-2cpAmvGq.js} +1 -1
- package/dist/assets/{ProvidersList-6A6N2eDT.js → ProvidersList-Dot21pAy.js} +1 -1
- package/dist/assets/{RuntimeConfig-B3k_dMdJ.js → RuntimeConfig-BNw_Ms_Y.js} +1 -1
- package/dist/assets/{SecretsConfig-BeCRCCEW.js → SecretsConfig-z8M3PDJP.js} +1 -1
- package/dist/assets/{SessionsConfig-M32Qm7cL.js → SessionsConfig-XVHZ-FG5.js} +1 -1
- package/dist/assets/{action-link-DsAjsb68.js → action-link-CpPJJN-z.js} +1 -1
- package/dist/assets/{card-uTj7-9XS.js → card-DsZ2Am92.js} +1 -1
- package/dist/assets/chat-message-Jxa8JFA_.js +9 -0
- package/dist/assets/{dialog-FRtXcCmk.js → dialog-BysNu5hM.js} +1 -1
- package/dist/assets/index-B_OeEGic.css +1 -0
- package/dist/assets/index-Bny21Br0.js +2 -0
- package/dist/assets/{label-DAhEgM6-.js → label-q6RASlER.js} +1 -1
- package/dist/assets/{page-layout-DMpNQawS.js → page-layout-WiVrFc8t.js} +1 -1
- package/dist/assets/{switch-D8lSFzq4.js → switch-DM_YYUgB.js} +1 -1
- package/dist/assets/{tabs-custom-CsFrOXUS.js → tabs-custom-mlgm-IGH.js} +1 -1
- package/dist/assets/{useConfig-Cjlx5C-1.js → useConfig-BOn-kp8G.js} +1 -1
- package/dist/assets/{useConfirmDialog-D3eI0Hfj.js → useConfirmDialog-DamaA60g.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/src/components/chat/ChatPage.tsx +147 -46
- package/src/lib/chat-message.ts +72 -3
- package/src/lib/i18n.ts +3 -0
- package/dist/assets/ChatPage-Bxs3X5OC.js +0 -32
- package/dist/assets/chat-message-DZV2Z5oc.js +0 -5
- package/dist/assets/index-BsDasSXm.css +0 -1
- package/dist/assets/index-Dw8Ss2WH.js +0 -2
package/src/lib/chat-message.ts
CHANGED
|
@@ -100,6 +100,34 @@ function toToolName(value: unknown): string {
|
|
|
100
100
|
return value.trim();
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
function hasToolCalls(message: SessionMessageView): boolean {
|
|
104
|
+
return Array.isArray(message.tool_calls) && message.tool_calls.length > 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function mergeMessageContent(base: unknown, addition: unknown): unknown {
|
|
108
|
+
const left = extractMessageText(base).trim();
|
|
109
|
+
const right = extractMessageText(addition).trim();
|
|
110
|
+
if (!left) {
|
|
111
|
+
return right;
|
|
112
|
+
}
|
|
113
|
+
if (!right) {
|
|
114
|
+
return left;
|
|
115
|
+
}
|
|
116
|
+
return `${left}\n\n${right}`;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function mergeReasoningContent(base: unknown, addition: unknown): string | undefined {
|
|
120
|
+
const left = typeof base === 'string' ? base.trim() : '';
|
|
121
|
+
const right = typeof addition === 'string' ? addition.trim() : '';
|
|
122
|
+
if (!left) {
|
|
123
|
+
return right || undefined;
|
|
124
|
+
}
|
|
125
|
+
if (!right) {
|
|
126
|
+
return left;
|
|
127
|
+
}
|
|
128
|
+
return `${left}\n\n${right}`;
|
|
129
|
+
}
|
|
130
|
+
|
|
103
131
|
export function normalizeChatRole(message: Pick<SessionMessageView, 'role' | 'name' | 'tool_call_id' | 'tool_calls'>): ChatRole {
|
|
104
132
|
const role = message.role.toLowerCase().trim();
|
|
105
133
|
if (role === 'user') {
|
|
@@ -225,11 +253,12 @@ export function combineToolCallAndResults(messages: SessionMessageView[]): Sessi
|
|
|
225
253
|
const consumedCallIds = new Set<string>();
|
|
226
254
|
|
|
227
255
|
for (const message of cloned) {
|
|
228
|
-
if (normalizeChatRole(message) !== 'assistant' || !
|
|
256
|
+
if (normalizeChatRole(message) !== 'assistant' || !hasToolCalls(message)) {
|
|
229
257
|
continue;
|
|
230
258
|
}
|
|
231
259
|
|
|
232
|
-
message.tool_calls
|
|
260
|
+
const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : [];
|
|
261
|
+
message.tool_calls = toolCalls.map((call) => {
|
|
233
262
|
if (!isRecord(call) || typeof call.id !== 'string') {
|
|
234
263
|
return call;
|
|
235
264
|
}
|
|
@@ -247,7 +276,7 @@ export function combineToolCallAndResults(messages: SessionMessageView[]): Sessi
|
|
|
247
276
|
}) as Array<Record<string, unknown>>;
|
|
248
277
|
}
|
|
249
278
|
|
|
250
|
-
|
|
279
|
+
const mergedToolResults = cloned.filter((message) => {
|
|
251
280
|
if (normalizeChatRole(message) !== 'tool') {
|
|
252
281
|
return true;
|
|
253
282
|
}
|
|
@@ -256,6 +285,46 @@ export function combineToolCallAndResults(messages: SessionMessageView[]): Sessi
|
|
|
256
285
|
}
|
|
257
286
|
return !consumedCallIds.has(message.tool_call_id.trim());
|
|
258
287
|
});
|
|
288
|
+
|
|
289
|
+
const mergedFollowups: SessionMessageView[] = [];
|
|
290
|
+
for (let index = 0; index < mergedToolResults.length; index += 1) {
|
|
291
|
+
const current = mergedToolResults[index];
|
|
292
|
+
if (normalizeChatRole(current) !== 'assistant' || !hasToolCalls(current)) {
|
|
293
|
+
mergedFollowups.push(current);
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
let merged = current;
|
|
298
|
+
let cursor = index + 1;
|
|
299
|
+
while (cursor < mergedToolResults.length) {
|
|
300
|
+
const candidate = mergedToolResults[cursor];
|
|
301
|
+
if (normalizeChatRole(candidate) !== 'assistant') {
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
if (hasToolCalls(candidate) || typeof candidate.tool_call_id === 'string') {
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const candidateText = extractMessageText(candidate.content).trim();
|
|
309
|
+
const candidateReasoning = typeof candidate.reasoning_content === 'string' && candidate.reasoning_content.trim();
|
|
310
|
+
if (!candidateText && !candidateReasoning) {
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
merged = {
|
|
315
|
+
...merged,
|
|
316
|
+
content: mergeMessageContent(merged.content, candidate.content),
|
|
317
|
+
reasoning_content: mergeReasoningContent(merged.reasoning_content, candidate.reasoning_content),
|
|
318
|
+
timestamp: candidate.timestamp
|
|
319
|
+
};
|
|
320
|
+
cursor += 1;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
mergedFollowups.push(merged);
|
|
324
|
+
index = cursor - 1;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return mergedFollowups;
|
|
259
328
|
}
|
|
260
329
|
|
|
261
330
|
export function groupChatMessages(messages: SessionMessageView[]): GroupedChatMessage[] {
|
package/src/lib/i18n.ts
CHANGED
|
@@ -422,6 +422,9 @@ export const LABELS: Record<string, { zh: string; en: string }> = {
|
|
|
422
422
|
chatInputHint: { zh: '支持多轮上下文,默认走当前会话。', en: 'Multi-turn context is preserved in the current session.' },
|
|
423
423
|
chatSend: { zh: '发送', en: 'Send' },
|
|
424
424
|
chatSending: { zh: '发送中...', en: 'Sending...' },
|
|
425
|
+
chatQueueSend: { zh: '排队发送', en: 'Queue' },
|
|
426
|
+
chatQueuedHintPrefix: { zh: '当前有', en: 'Queued' },
|
|
427
|
+
chatQueuedHintSuffix: { zh: '条消息待发送。', en: 'pending messages.' },
|
|
425
428
|
chatDeleteSession: { zh: '删除会话', en: 'Delete Session' },
|
|
426
429
|
chatDeleteSessionConfirm: { zh: '确认删除当前会话?', en: 'Delete the current session?' },
|
|
427
430
|
chatSendFailed: { zh: '发送消息失败', en: 'Failed to send message' },
|