-
Notifications
You must be signed in to change notification settings - Fork 61.1k
fix: fixed the conflict BUG between model thinking mode and line break parsing. #6616
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
β¦k parsing. Co-authored-by: MrrDrr [email protected] Co-authored-by: NakanoMiku39 [email protected]
WalkthroughRefines thinking-mode output formatting in streamWithThink within app/utils/chat.ts: conditional newline insertion before thinking blocks and consistent per-line quoting using a prefixed "> ". Removes prior special-casing of internal newlines. Adds a non-functional comment in a parse-error catch. Normal-mode logic unchanged. Changes
Estimated code review effortπ― 2 (Simple) | β±οΈ ~10 minutes Poem
Tip π Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. β¨ Finishing Touches
π§ͺ Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. πͺ§ TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and canβt be posted inline due to platform limitations.
β οΈ Outside diff range comments (1)
app/utils/chat.ts (1)
602-617
: Handle β¦ in the same chunk and closing tags while already in thinking mode; avoid trimming user contentThe fallback tag handling runs only when
!chunk.isThinking
, misses end-tags mid-session, and theelse if
chain canβt handle chunks containing both start and end tags. Also,.trim()
drops intentional leading/trailing newlines. Make the tag handling unconditional, support both tags in one chunk, and preserve whitespace.- // deal with <think> and </think> tags start - if (!chunk.isThinking) { - if (chunk.content.startsWith("<think>")) { - chunk.isThinking = true; - chunk.content = chunk.content.slice(7).trim(); - lastIsThinkingTagged = true; - } else if (chunk.content.endsWith("</think>")) { - chunk.isThinking = false; - chunk.content = chunk.content.slice(0, -8).trim(); - lastIsThinkingTagged = false; - } else if (lastIsThinkingTagged) { - chunk.isThinking = true; - } - } - // deal with <think> and </think> tags start + // deal with <think> and </think> tags (fallback if parseSSE didn't set isThinking) + { + const starts = chunk.content.startsWith("<think>"); + const ends = chunk.content.endsWith("</think>"); + if (starts) chunk.content = chunk.content.slice(7); // keep whitespace + if (ends) chunk.content = chunk.content.slice(0, -8); // keep whitespace + + if (starts && ends) { + // one-chunk think block + chunk.isThinking = false; + lastIsThinkingTagged = false; + } else if (starts) { + chunk.isThinking = true; + lastIsThinkingTagged = true; + } else if (ends) { + chunk.isThinking = false; + lastIsThinkingTagged = false; + } else if (lastIsThinkingTagged) { + chunk.isThinking = true; + } + }
π§Ή Nitpick comments (1)
app/utils/chat.ts (1)
633-633
: Quote CRLF tooSupport Windows-style newlines by matching
\r?\n
.- remainText += chunk.content.replace(/\n/g, "\n> "); + remainText += chunk.content.replace(/\r?\n/g, "\n> ");
π Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
π‘ Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
π Files selected for processing (1)
app/utils/chat.ts
(1 hunks)
if (remainText.length > 0 && !remainText.endsWith("\n")) { | ||
remainText += "\n"; | ||
} | ||
remainText += "> " + chunk.content; | ||
} else { | ||
// Handle newlines in thinking content | ||
if (chunk.content.includes("\n\n")) { | ||
const lines = chunk.content.split("\n\n"); | ||
remainText += lines.join("\n\n> "); | ||
} else { | ||
remainText += chunk.content; | ||
} | ||
remainText += "> "; | ||
} | ||
// Append content, ensuring newlines are quoted | ||
remainText += chunk.content.replace(/\n/g, "\n> "); | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking-mode chunks can lose the >
prefix after a newline split across SSE chunks
When a thinking chunk ends with \n
and the next chunk continues thinking, the first line of the next chunk wonβt be prefixed because "> "
is only added on block start. Add a prefix whenever weβre still in thinking mode and remainText
currently ends with \n
.
if (chunk.isThinking) {
// If in thinking mode
if (!isInThinkingMode || isThinkingChanged) {
// If this is a new thinking block or mode changed, add prefix
isInThinkingMode = true;
if (remainText.length > 0 && !remainText.endsWith("\n")) {
remainText += "\n";
}
remainText += "> ";
- }
+ } else if (remainText.endsWith("\n")) {
+ // preserve quoting across chunk boundaries
+ remainText += "> ";
+ }
// Append content, ensuring newlines are quoted
- remainText += chunk.content.replace(/\n/g, "\n> ");
+ remainText += chunk.content.replace(/\n/g, "\n> ");
π Committable suggestion
βΌοΈ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if (remainText.length > 0 && !remainText.endsWith("\n")) { | |
remainText += "\n"; | |
} | |
remainText += "> " + chunk.content; | |
} else { | |
// Handle newlines in thinking content | |
if (chunk.content.includes("\n\n")) { | |
const lines = chunk.content.split("\n\n"); | |
remainText += lines.join("\n\n> "); | |
} else { | |
remainText += chunk.content; | |
} | |
remainText += "> "; | |
} | |
// Append content, ensuring newlines are quoted | |
remainText += chunk.content.replace(/\n/g, "\n> "); | |
} else { | |
if (remainText.length > 0 && !remainText.endsWith("\n")) { | |
remainText += "\n"; | |
} | |
remainText += "> "; | |
} else if (remainText.endsWith("\n")) { | |
// preserve quoting across chunk boundaries | |
remainText += "> "; | |
} | |
// Append content, ensuring newlines are quoted | |
remainText += chunk.content.replace(/\n/g, "\n> "); | |
} else { |
π€ Prompt for AI Agents
In app/utils/chat.ts around lines 627 to 634, the logic that prepares quoted
"thinking" text must also add a "> " prefix when remainText already ends with a
newline (split across SSE chunks). Modify the branch so that when still in
thinking mode and remainText.endsWith("\n") you append "> " before adding the
next chunk, and keep the existing logic that adds a newline when remainText is
non-empty and does not end with "\n"; then proceed to append the chunk content
with .replace(/\n/g, "\n> ") as before.
π» εζ΄η±»ε | Change Type
π εζ΄θ―΄ζ | Description of Change
Resolves the issue where line breaks in model-generated reasoning content are not parsed correctly in the current version of NextChat.
After this adjustment, all reasoning mode content will be properly enclosed within Markdown blockquotes.
π θ‘₯ε δΏ‘ζ― | Additional Information
before and after:
Co-authored-by: MrrDrr [email protected]
Co-authored-by: NakanoMiku39 [email protected]
Summary by CodeRabbit
Bug Fixes
Style
Other