From 229aba7c3e33a95c9c654826504ffc4f163f8003 Mon Sep 17 00:00:00 2001 From: Pascal Date: Fri, 16 Jan 2026 19:49:48 +0100 Subject: [PATCH] fix: strip reasoning content and UI proprietary tags from prompts TODO: add toggle and ensure backend API compliance for reasoning format --- .../server/webui/src/lib/constants/agentic.ts | 4 +++ .../webui/src/lib/services/chat.service.ts | 34 ++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/tools/server/webui/src/lib/constants/agentic.ts b/tools/server/webui/src/lib/constants/agentic.ts index 5b57294eb4..a877c600fe 100644 --- a/tools/server/webui/src/lib/constants/agentic.ts +++ b/tools/server/webui/src/lib/constants/agentic.ts @@ -36,6 +36,10 @@ export const AGENTIC_REGEX = { EARLY_MATCH: /<<>>([\s\S]*)$/, // Matches partial marker at end of content PARTIAL_MARKER: /<<<[A-Za-z_]*$/, + // Matches reasoning content blocks (including tags) + REASONING_BLOCK: /<<>>[\s\S]*?<<>>/g, + // Matches an opening reasoning tag and any remaining content (unterminated) + REASONING_OPEN: /<<>>[\s\S]*$/, // Matches tool name inside content TOOL_NAME_EXTRACT: /<<]+)>>>/ } as const; diff --git a/tools/server/webui/src/lib/services/chat.service.ts b/tools/server/webui/src/lib/services/chat.service.ts index 861363e5e1..5bf8cd9a0e 100644 --- a/tools/server/webui/src/lib/services/chat.service.ts +++ b/tools/server/webui/src/lib/services/chat.service.ts @@ -1,5 +1,7 @@ import { getJsonHeaders } from '$lib/utils'; +import { AGENTIC_REGEX } from '$lib/constants/agentic'; import { AttachmentType } from '$lib/enums'; +import type { ApiChatMessageContentPart } from '$lib/types/api'; /** * ChatService - Low-level API communication layer for Chat Completions @@ -34,6 +36,34 @@ import { AttachmentType } from '$lib/enums'; * - Request lifecycle management (abort via AbortSignal) */ export class ChatService { + private static stripReasoningContent( + content: ApiChatMessageData['content'] | null | undefined + ): ApiChatMessageData['content'] | null | undefined { + if (!content) { + return content; + } + + if (typeof content === 'string') { + return content + .replace(AGENTIC_REGEX.REASONING_BLOCK, '') + .replace(AGENTIC_REGEX.REASONING_OPEN, ''); + } + + if (!Array.isArray(content)) { + return content; + } + + return content.map((part: ApiChatMessageContentPart) => { + if (part.type !== 'text' || !part.text) return part; + return { + ...part, + text: part.text + .replace(AGENTIC_REGEX.REASONING_BLOCK, '') + .replace(AGENTIC_REGEX.REASONING_OPEN, '') + }; + }); + } + /** * * @@ -122,7 +152,9 @@ export class ChatService { const requestBody: ApiChatCompletionRequest = { messages: normalizedMessages.map((msg: ApiChatMessageData) => ({ role: msg.role, - content: msg.content, + // Strip reasoning tags/content from the prompt to avoid polluting KV cache. + // TODO: investigate backend expectations for reasoning tags and add a toggle if needed. + content: ChatService.stripReasoningContent(msg.content), tool_calls: msg.tool_calls, tool_call_id: msg.tool_call_id })),