import type { AssistantMessage } from "@mariozechner/pi-ai"; import { describe, expect, it } from "vitest"; import { extractAssistantText } from "./pi-embedded-utils.js"; describe("extractAssistantText", () => { it("strips Minimax tool invocation XML from text", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: ` netstat -tlnp | grep 18789 `, }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe(""); }); it("strips multiple tool invocations", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: `Let me check that. /home/admin/test.txt `, }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("Let me check that."); }); it("keeps invoke snippets without Minimax markers", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: `Example:\n\nls\n`, }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe( `Example:\n\nls\n`, ); }); it("preserves normal text without tool invocations", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: "This is a normal response without any tool calls.", }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("This is a normal response without any tool calls."); }); it("strips Minimax tool invocations with extra attributes", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: `Before\nls\n\nAfter`, }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("Before\nAfter"); }); it("strips minimax tool_call open and close tags", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: "StartInnerEnd", }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("StartInnerEnd"); }); it("ignores invoke blocks without minimax markers", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: "BeforeKeepAfter", }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("BeforeKeepAfter"); }); it("strips invoke blocks when minimax markers are present elsewhere", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: "BeforeDropAfter", }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("BeforeAfter"); }); it("strips invoke blocks with nested tags", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: `A1B`, }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("AB"); }); it("strips tool XML mixed with regular content", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: `I'll help you with that. ls -la Here are the results.`, }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("I'll help you with that.\nHere are the results."); }); it("handles multiple invoke blocks in one message", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: `First check. file1.txt Second check. pwd Done.`, }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("First check.\nSecond check.\nDone."); }); it("handles stray closing tags without opening tags", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: "Some text here.More text.", }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("Some text here.More text."); }); it("returns empty string when message is only tool invocations", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: ` test `, }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe(""); }); it("handles multiple text blocks", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: "First block.", }, { type: "text", text: ` ls `, }, { type: "text", text: "Third block.", }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("First block.\nThird block."); }); it("strips downgraded Gemini tool call text representations", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: `[Tool Call: exec (ID: toolu_vrtx_014w1P6B6w4V92v4VzG7Qk12)] Arguments: { "command": "git status", "timeout": 120000 }`, }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe(""); }); it("strips multiple downgraded tool calls", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: `[Tool Call: read (ID: toolu_1)] Arguments: { "path": "/some/file.txt" } [Tool Call: exec (ID: toolu_2)] Arguments: { "command": "ls -la" }`, }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe(""); }); it("strips tool results for downgraded calls", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: `[Tool Result for ID toolu_123] {"status": "ok", "data": "some result"}`, }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe(""); }); it("preserves text around downgraded tool calls", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: `Let me check that for you. [Tool Call: browser (ID: toolu_abc)] Arguments: { "action": "act", "request": "click button" }`, }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("Let me check that for you."); }); it("preserves trailing text after downgraded tool call blocks", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: `Intro text. [Tool Call: read (ID: toolu_1)] Arguments: { "path": "/tmp/file.txt" } Back to the user.`, }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("Intro text.\nBack to the user."); }); it("handles multiple text blocks with tool calls and results", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: "Here's what I found:", }, { type: "text", text: `[Tool Call: read (ID: toolu_1)] Arguments: { "path": "/test.txt" }`, }, { type: "text", text: `[Tool Result for ID toolu_1] File contents here`, }, { type: "text", text: "Done checking.", }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("Here's what I found:\nDone checking."); }); it("strips thinking tags from text content", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: "El usuario quiere retomar una tarea...Aquí está tu respuesta.", }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("Aquí está tu respuesta."); }); it("strips thinking tags with attributes", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: `HiddenVisible`, }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("Visible"); }); it("strips thinking tags without closing tag", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: "Pensando sobre el problema...", }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe(""); }); it("strips thinking tags with various formats", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: "Beforeinternal reasoningAfter", }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("BeforeAfter"); }); it("strips antthinking tags", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: "Some reasoningThe actual answer.", }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("The actual answer."); }); it("strips thought tags", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: "Internal deliberationFinal response.", }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("Final response."); }); it("handles nested or multiple thinking blocks", () => { const msg: AssistantMessage = { role: "assistant", content: [ { type: "text", text: "Startfirst thoughtMiddlesecond thoughtEnd", }, ], timestamp: Date.now(), }; const result = extractAssistantText(msg); expect(result).toBe("StartMiddleEnd"); }); });