fix(reasoning): wrap multiline italic text per line for Telegram
Telegram and other markdown parsers don't support underscore markdown spanning multiple lines. The reasoning block now wraps each line individually with underscores, so multiline reasoning text renders correctly in italics. Fixes #2060 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
6859e1e6a6
commit
d5a0909825
@ -1,6 +1,6 @@
|
|||||||
import type { AssistantMessage } from "@mariozechner/pi-ai";
|
import type { AssistantMessage } from "@mariozechner/pi-ai";
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import { extractAssistantText } from "./pi-embedded-utils.js";
|
import { extractAssistantText, formatReasoningMessage } from "./pi-embedded-utils.js";
|
||||||
|
|
||||||
describe("extractAssistantText", () => {
|
describe("extractAssistantText", () => {
|
||||||
it("strips Minimax tool invocation XML from text", () => {
|
it("strips Minimax tool invocation XML from text", () => {
|
||||||
@ -508,3 +508,28 @@ File contents here`,
|
|||||||
expect(result).toBe("StartMiddleEnd");
|
expect(result).toBe("StartMiddleEnd");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("formatReasoningMessage", () => {
|
||||||
|
it("returns empty string for empty input", () => {
|
||||||
|
expect(formatReasoningMessage("")).toBe("");
|
||||||
|
expect(formatReasoningMessage(" ")).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("wraps single line in italics", () => {
|
||||||
|
expect(formatReasoningMessage("Because it helps")).toBe("Reasoning:\n_Because it helps_");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("wraps each line individually for multiline text", () => {
|
||||||
|
const input = "line one\nline two\nline three";
|
||||||
|
expect(formatReasoningMessage(input)).toBe("Reasoning:\n_line one_\n_line two_\n_line three_");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("preserves empty lines without wrapping them", () => {
|
||||||
|
const input = "line one\n\nline three";
|
||||||
|
expect(formatReasoningMessage(input)).toBe("Reasoning:\n_line one_\n\n_line three_");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("trims leading and trailing whitespace from input", () => {
|
||||||
|
expect(formatReasoningMessage(" text ")).toBe("Reasoning:\n_text_");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@ -209,9 +209,15 @@ export function extractAssistantThinking(msg: AssistantMessage): string {
|
|||||||
export function formatReasoningMessage(text: string): string {
|
export function formatReasoningMessage(text: string): string {
|
||||||
const trimmed = text.trim();
|
const trimmed = text.trim();
|
||||||
if (!trimmed) return "";
|
if (!trimmed) return "";
|
||||||
// Show reasoning in italics (cursive) for markdown-friendly surfaces (Discord, etc.).
|
// Show reasoning in italics (cursive) for markdown-friendly surfaces.
|
||||||
|
// Wrap each line individually because many markdown parsers (Telegram, etc.)
|
||||||
|
// don't support underscores spanning multiple lines.
|
||||||
// Keep the plain "Reasoning:" prefix so existing parsing/detection keeps working.
|
// Keep the plain "Reasoning:" prefix so existing parsing/detection keeps working.
|
||||||
return `Reasoning:\n_${trimmed}_`;
|
const italicLines = trimmed
|
||||||
|
.split("\n")
|
||||||
|
.map((line) => (line ? `_${line}_` : ""))
|
||||||
|
.join("\n");
|
||||||
|
return `Reasoning:\n${italicLines}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ThinkTaggedSplitBlock =
|
type ThinkTaggedSplitBlock =
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user