fix(streaming): strip Gemma 4 thinking token delimiter in all paths — closes #607
Fixes <|turn|>thinking delimiter (was wrong as <|turn>thinking) in api/streaming.py, static/messages.js, and static/ui.js. Adds 13 regression tests. Independent review by @nesquena.
This commit is contained in:
11
static/ui.js
11
static/ui.js
@@ -1095,7 +1095,7 @@ function _messageHasReasoningPayload(m){
|
||||
if(!m||m.role!=='assistant') return false;
|
||||
if(m.reasoning) return true;
|
||||
if(Array.isArray(m.content)) return m.content.some(p=>p&&(p.type==='thinking'||p.type==='reasoning'));
|
||||
return /<think>[\s\S]*?<\/think>|<\|channel>thought\n[\s\S]*?<channel\|>/.test(String(m.content||''));
|
||||
return /<think>[\s\S]*?<\/think>|<\|channel>thought\n[\s\S]*?<channel\|>|<\|turn\|>thinking\n[\s\S]*?<turn\|>/.test(String(m.content||''));
|
||||
}
|
||||
function _assistantRoleHtml(tsTitle=''){
|
||||
const _bn=window._botName||'Hermes';
|
||||
@@ -1167,12 +1167,21 @@ function renderMessages(){
|
||||
content=content.replace(/<think>[\s\S]*?<\/think>\s*/,'').trimStart();
|
||||
}
|
||||
if(!thinkingText){
|
||||
// Historical name "gemmaMatch" refers to MiniMax <|channel>thought format.
|
||||
const gemmaMatch=content.match(/<\|channel>thought\n([\s\S]*?)<channel\|>/);
|
||||
if(gemmaMatch){
|
||||
thinkingText=gemmaMatch[1].trim();
|
||||
content=content.replace(/<\|channel>thought\n[\s\S]*?<channel\|>\s*/,'').trimStart();
|
||||
}
|
||||
}
|
||||
if(!thinkingText){
|
||||
// Gemma 4 uses asymmetric <|turn|>thinking\n...<turn|> delimiters.
|
||||
const gemmaTurnMatch=content.match(/<\|turn\|>thinking\n([\s\S]*?)<turn\|>/);
|
||||
if(gemmaTurnMatch){
|
||||
thinkingText=gemmaTurnMatch[1].trim();
|
||||
content=content.replace(/<\|turn\|>thinking\n[\s\S]*?<turn\|>\s*/,'').trimStart();
|
||||
}
|
||||
}
|
||||
}
|
||||
const isUser=m.role==='user';
|
||||
const isLastAssistant=!isUser&&vi===visWithIdx.length-1;
|
||||
|
||||
Reference in New Issue
Block a user