Skip to content

Commit 569b9d6

Browse files
committed
Add support for delta.reasoning_content in llama-server's webui
1 parent 7845240 commit 569b9d6

File tree

4 files changed

+35
-7
lines changed

4 files changed

+35
-7
lines changed

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,25 @@ export default function ChatMessage({
5858
// for reasoning model, we split the message into content and thought
5959
// TODO: implement this as remark/rehype plugin in the future
6060
const { content, thought, isThinking }: SplitMessage = useMemo(() => {
61-
if (msg.content === null || msg.role !== 'assistant') {
61+
if (msg.role !== 'assistant') {
6262
return { content: msg.content };
6363
}
64+
65+
// Handle case where we have reasoningContent (content can be null or empty)
66+
if (msg.reasoningContent.length > 0) {
67+
return {
68+
content: msg.content || '',
69+
thought: msg.reasoningContent,
70+
isThinking: msg.content === null || msg.content === '',
71+
};
72+
}
73+
74+
// If content is null or empty, return as-is
75+
if (msg.content === null || msg.content === '') {
76+
return { content: msg.content };
77+
}
78+
79+
// perhaps there are <think>...</think> tags in the regular content
6480
let actualContent = '';
6581
let thought = '';
6682
let isThinking = false;

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ export const AppContextProvider = ({
188188
content: null,
189189
parent: leafNodeId,
190190
children: [],
191+
reasoningContent: '',
191192
};
192193
setPending(convId, pendingMsg);
193194

@@ -254,13 +255,23 @@ 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+
259+
const reasoningContent = chunk.choices[0].delta.reasoning_content;
260+
if (reasoningContent) {
261+
const lastContent = pendingMsg.reasoningContent || '';
260262
pendingMsg = {
261263
...pendingMsg,
262-
content: lastContent + addedContent,
264+
reasoningContent: lastContent + reasoningContent,
263265
};
266+
} else {
267+
const addedContent = chunk.choices[0].delta.content;
268+
const lastContent = pendingMsg.content || '';
269+
if (addedContent) {
270+
pendingMsg = {
271+
...pendingMsg,
272+
content: lastContent + addedContent,
273+
};
274+
}
264275
}
265276
const timings = chunk.timings;
266277
if (timings && config.showTokensPerSecond) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export interface Message {
4040
type: 'text' | 'root';
4141
timestamp: number; // timestamp from Date.now()
4242
role: 'user' | 'assistant' | 'system';
43+
reasoningContent?: string;
4344
content: string;
4445
timings?: TimingReport;
4546
extra?: MessageExtra[];

tools/server/webui/vite.config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ export default defineConfig({
7171
plugins: process.env.ANALYZE ? FRONTEND_PLUGINS : BUILD_PLUGINS,
7272
server: {
7373
proxy: {
74-
'/v1': 'http://localhost:8080',
75-
'/props': 'http://localhost:8080',
74+
'/v1': 'http://10.0.1.50:9999',
75+
'/props': 'http://10.0.1.50:9999',
7676
},
7777
headers: {
7878
'Cross-Origin-Embedder-Policy': 'require-corp',

0 commit comments

Comments
 (0)