Skip to content

Commit 98acde2

Browse files
committed
server: update webui to new reasoning_content diff
1 parent 961635c commit 98acde2

File tree

4 files changed

+20
-41
lines changed

4 files changed

+20
-41
lines changed

tools/server/webui/src/components/ChatMessage.tsx

Lines changed: 5 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,6 @@ import {
1212
import ChatInputExtraContextItem from './ChatInputExtraContextItem';
1313
import { BtnWithTooltips } from '../utils/common';
1414

15-
interface SplitMessage {
16-
content: PendingMessage['content'];
17-
thought?: string;
18-
isThinking?: boolean;
19-
}
20-
2115
export default function ChatMessage({
2216
msg,
2317
siblingLeafNodeIds,
@@ -55,32 +49,6 @@ export default function ChatMessage({
5549
const nextSibling = siblingLeafNodeIds[siblingCurrIdx + 1];
5650
const prevSibling = siblingLeafNodeIds[siblingCurrIdx - 1];
5751

58-
// for reasoning model, we split the message into content and thought
59-
// TODO: implement this as remark/rehype plugin in the future
60-
const { content, thought, isThinking }: SplitMessage = useMemo(() => {
61-
if (msg.content === null || msg.role !== 'assistant') {
62-
return { content: msg.content };
63-
}
64-
let actualContent = '';
65-
let thought = '';
66-
let isThinking = false;
67-
let thinkSplit = msg.content.split('<think>', 2);
68-
actualContent += thinkSplit[0];
69-
while (thinkSplit[1] !== undefined) {
70-
// <think> tag found
71-
thinkSplit = thinkSplit[1].split('</think>', 2);
72-
thought += thinkSplit[0];
73-
isThinking = true;
74-
if (thinkSplit[1] !== undefined) {
75-
// </think> closing tag found
76-
isThinking = false;
77-
thinkSplit = thinkSplit[1].split('<think>', 2);
78-
actualContent += thinkSplit[0];
79-
}
80-
}
81-
return { content: actualContent, thought, isThinking };
82-
}, [msg]);
83-
8452
if (!viewingChat) return null;
8553

8654
const isUser = msg.role === 'user';
@@ -141,7 +109,7 @@ export default function ChatMessage({
141109
{/* not editing content, render message */}
142110
{editingContent === null && (
143111
<>
144-
{content === null ? (
112+
{msg.content === null ? (
145113
<>
146114
{/* show loading dots for pending message */}
147115
<span className="loading loading-dots loading-md"></span>
@@ -150,16 +118,16 @@ export default function ChatMessage({
150118
<>
151119
{/* render message as markdown */}
152120
<div dir="auto" tabIndex={0}>
153-
{thought && (
121+
{msg.reasoningContent && (
154122
<ThoughtProcess
155-
isThinking={!!isThinking && !!isPending}
156-
content={thought}
123+
isThinking={!!msg.reasoningContent && !!isPending}
124+
content={msg.reasoningContent}
157125
open={config.showThoughtInProgress}
158126
/>
159127
)}
160128

161129
<MarkdownDisplay
162-
content={content}
130+
content={msg.content}
163131
isGenerating={isPending}
164132
/>
165133
</div>

tools/server/webui/src/utils/app.context.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ export const AppContextProvider = ({
186186
timestamp: pendingId,
187187
role: 'assistant',
188188
content: null,
189+
reasoningContent: null,
189190
parent: leafNodeId,
190191
children: [],
191192
};
@@ -254,12 +255,15 @@ export const AppContextProvider = ({
254255
if (chunk.error) {
255256
throw new Error(chunk.error?.message || 'Unknown error');
256257
}
257-
const addedContent = chunk.choices[0].delta.content;
258-
const lastContent = pendingMsg.content || '';
259-
if (addedContent) {
258+
const addedContent = chunk.choices[0].delta.content ?? '';
259+
const addedReasoningContent =
260+
chunk.choices[0].delta.reasoning_content ?? '';
261+
if (addedContent.length > 0 || addedReasoningContent.length > 0) {
260262
pendingMsg = {
261263
...pendingMsg,
262-
content: lastContent + addedContent,
264+
content: (pendingMsg.content ?? '') + addedContent,
265+
reasoningContent:
266+
(pendingMsg.reasoningContent ?? '') + addedReasoningContent,
263267
};
264268
}
265269
const timings = chunk.timings;
@@ -324,6 +328,7 @@ export const AppContextProvider = ({
324328
convId,
325329
role: 'user',
326330
content,
331+
reasoningContent: null,
327332
extra,
328333
parent: leafNodeId,
329334
children: [],
@@ -367,6 +372,7 @@ export const AppContextProvider = ({
367372
convId,
368373
role: 'user',
369374
content,
375+
reasoningContent: null,
370376
extra,
371377
parent: parentNodeId,
372378
children: [],

tools/server/webui/src/utils/storage.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ const StorageUtils = {
111111
timestamp: now,
112112
role: 'system',
113113
content: '',
114+
reasoningContent: null,
114115
parent: -1,
115116
children: [],
116117
});
@@ -229,6 +230,7 @@ interface LSMessage {
229230
id: number;
230231
role: 'user' | 'assistant' | 'system';
231232
content: string;
233+
reasoningContent: string | null;
232234
timings?: TimingReport;
233235
}
234236
async function migrationLStoIDB() {
@@ -267,6 +269,7 @@ async function migrationLStoIDB() {
267269
timestamp: rootId,
268270
role: 'system',
269271
content: '',
272+
reasoningContent: null,
270273
parent: -1,
271274
children: [firstMsg.id],
272275
});

tools/server/webui/src/utils/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export interface Message {
4141
timestamp: number; // timestamp from Date.now()
4242
role: 'user' | 'assistant' | 'system';
4343
content: string;
44+
reasoningContent: string | null;
4445
timings?: TimingReport;
4546
extra?: MessageExtra[];
4647
// node based system for branching
@@ -112,6 +113,7 @@ export interface ViewingChat {
112113

113114
export type PendingMessage = Omit<Message, 'content'> & {
114115
content: string | null;
116+
reasoningContent: string | null;
115117
};
116118

117119
export enum CanvasType {

0 commit comments

Comments
 (0)