Fix: Better thinking signal parsing for GPT-oSS streaming format
All checks were successful
BotUI CI/CD / build (push) Successful in 39s

This commit is contained in:
Rodrigo Rodriguez (Pragmatismo) 2026-04-14 18:50:05 -03:00
parent 3966cbd647
commit 99209fa1dd

View file

@ -817,55 +817,65 @@ function finalizeStreaming() {
}
function processMessage(data) {
// If content contains JSON signals, extract and handle them
if (data.content && typeof data.content === "string" && data.content.includes('{')) {
var signalRegex = /\{[^{}]*"type"\s*:\s*"(thinking|thinking_clear)"[^{}]*\}/g;
var match;
var hasAnySignal = false;
while ((match = signalRegex.exec(data.content)) !== null) {
try {
var jsonStr = match[0];
var inner = JSON.parse(jsonStr);
hasAnySignal = true;
if (inner.type === "thinking") {
showThinkingIndicator(inner.content);
isThinking = true; // Mark thinking state - hide bot messages
} else if (inner.type === "thinking_clear") {
hideThinkingIndicator();
isThinking = false; // Thinking done - allow bot messages to show
}
// Remove this signal from the content
data.content = data.content.replace(jsonStr, "");
// Reset regex index since we modified the string
signalRegex.lastIndex = 0;
} catch (e) {
console.error("Failed to parse signal:", e);
// Check if content contains thinking signals (from GPT-oSS model)
if (data.content && typeof data.content === "string") {
var content = data.content;
var hasThinking = content.includes('"type":"thinking"') || content.includes('"type":"thinking_clear"');
if (hasThinking) {
// Extract ALL thinking content and thinking_clear signals
var thinkingContent = [];
var hasThinkingClear = false;
// Match all thinking objects including those with content
var thinkingRegex = /\{"content":"[^"]*","type":"thinking"\}/g;
var clearRegex = /\{"type":"thinking_clear"\}/g;
// Find all thinking signals
var match;
while ((match = thinkingRegex.exec(content)) !== null) {
try {
var obj = JSON.parse(match[0]);
if (obj.content) {
thinkingContent.push(obj.content);
}
// Remove from content
content = content.replace(match[0], "");
} catch (e) {}
}
// Check for thinking_clear
if (clearRegex.test(content)) {
hasThinkingClear = true;
content = content.replace(clearRegex, "");
}
// Reset regex
thinkingRegex.lastIndex = 0;
// Show/hide thinking indicator
if (thinkingContent.length > 0) {
isThinking = true;
showThinkingIndicator(thinkingContent.join(""));
}
if (hasThinkingClear) {
isThinking = false;
hideThinkingIndicator();
}
// Update data.content with cleaned content
data.content = content;
// If content is now empty and not complete, skip
if (content.trim() === "" && !data.is_complete) {
return;
}
}
if (hasAnySignal && data.content.trim() === "" && !data.is_complete) {
return;
}
}
// Fallback for direct type matches
if (data.type === "thinking") {
showThinkingIndicator(data.content);
isThinking = true;
return;
}
if (data.type === "thinking_clear") {
hideThinkingIndicator();
isThinking = false;
return;
}
// Skip showing bot messages while thinking is active
if (isThinking && data.message_type === MessageType.BOT_RESPONSE) {
console.log("Hiding bot message while thinking:", data.content?.substring(0, 50));
console.log("Hiding bot message while thinking");
return;
}