fix(tui): strip <final> tags in TUI display (#1613)
Add <final> tag handling to stripThinkingTags() to prevent reasoning-tag provider responses from leaking incomplete tags during streaming. When using providers like google-antigravity/*, ollama, or minimax, the model wraps responses in <think>...</think> and <final>...</final> tags. The TUI was only stripping <think> tags, causing <final> to leak through and display as the response ~50% of the time. This is a defense-in-depth fix for the TUI layer. Fixes: #1561 Co-authored-by: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -21,5 +21,22 @@ describe("stripThinkingTags", () => {
|
||||
it("returns original text when no tags exist", () => {
|
||||
expect(stripThinkingTags("Hello")).toBe("Hello");
|
||||
});
|
||||
|
||||
it("strips <final>…</final> segments", () => {
|
||||
const input = "<final>\n\nHello there\n\n</final>";
|
||||
expect(stripThinkingTags(input)).toBe("Hello there\n\n");
|
||||
});
|
||||
|
||||
it("strips mixed <think> and <final> tags", () => {
|
||||
const input = "<think>reasoning</think>\n\n<final>Hello</final>";
|
||||
expect(stripThinkingTags(input)).toBe("Hello");
|
||||
});
|
||||
|
||||
it("handles incomplete <final tag gracefully", () => {
|
||||
// When streaming splits mid-tag, we may see "<final" without closing ">"
|
||||
// This should not crash and should handle gracefully
|
||||
expect(stripThinkingTags("<final\nHello")).toBe("<final\nHello");
|
||||
expect(stripThinkingTags("Hello</final>")).toBe("Hello");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -67,9 +67,9 @@ export function parseList(input: string): string[] {
|
||||
.filter((v) => v.length > 0);
|
||||
}
|
||||
|
||||
const THINKING_TAG_RE = /<\s*\/?\s*think(?:ing)?\s*>/gi;
|
||||
const THINKING_OPEN_RE = /<\s*think(?:ing)?\s*>/i;
|
||||
const THINKING_CLOSE_RE = /<\s*\/\s*think(?:ing)?\s*>/i;
|
||||
const THINKING_TAG_RE = /<\s*\/?\s*(?:think(?:ing)?|final)\s*>/gi;
|
||||
const THINKING_OPEN_RE = /<\s*(?:think(?:ing)?|final)\s*>/i;
|
||||
const THINKING_CLOSE_RE = /<\s*\/\s*(?:think(?:ing)?|final)\s*>/i;
|
||||
|
||||
export function stripThinkingTags(value: string): string {
|
||||
if (!value) return value;
|
||||
|
||||
Reference in New Issue
Block a user