Files
horus-3d/tests/unit/messageExtract.test.ts
T
Luke The Dev 4fa4f13558 First Release of Claw3D (#11)
Co-authored-by: iamlukethedev <iamlukethedev@users.noreply.github.com>
2026-03-19 23:14:04 -05:00

128 lines
4.4 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { normalizeAssistantDisplayText } from "@/lib/text/assistantText";
import {
buildAgentInstruction,
EXEC_APPROVAL_AUTO_RESUME_MARKER,
extractText,
extractTextCached,
extractThinking,
extractThinkingCached,
extractToolLines,
isUiMetadataPrefix,
stripUiMetadata,
} from "@/lib/text/message-extract";
describe("message-extract", () => {
it("strips envelope headers from user messages", () => {
const message = {
role: "user",
content:
"[Discord Guild #claw3d channel id:123 +0s 2026-02-01 00:00 UTC] hello there",
};
expect(extractText(message)).toBe("hello there");
});
it("removes <thinking>/<analysis> blocks from assistant-visible text", () => {
const message = {
role: "assistant",
content: "<thinking>Plan A</thinking>\n<analysis>Details</analysis>\nOk.",
};
expect(extractText(message)).toBe("Ok.");
});
it("strips assistant control prefixes in single- and double-bracket forms", () => {
expect(extractText({ role: "assistant", content: "[reply_to_current] hello" })).toBe("hello");
expect(extractText({ role: "assistant", content: "[[reply_to_current]] hello" })).toBe("hello");
});
it("extractTextCached matches extractText and is consistent", () => {
const message = { role: "user", content: "plain text" };
expect(extractTextCached(message)).toBe(extractText(message));
expect(extractTextCached(message)).toBe("plain text");
expect(extractTextCached(message)).toBe("plain text");
});
it("extractThinkingCached matches extractThinking and is consistent", () => {
const message = {
role: "assistant",
content: [{ type: "thinking", thinking: "Plan A" }],
};
expect(extractThinkingCached(message)).toBe(extractThinking(message));
expect(extractThinkingCached(message)).toBe("Plan A");
expect(extractThinkingCached(message)).toBe("Plan A");
});
it("formats tool call + tool result lines", () => {
const callMessage = {
role: "assistant",
content: [
{
type: "toolCall",
id: "call-1",
name: "functions.exec",
arguments: { command: "echo hi" },
},
],
};
const resultMessage = {
role: "toolResult",
toolCallId: "call-1",
toolName: "functions.exec",
details: { status: "ok", exitCode: 0 },
content: "hi\n",
};
const callLines = extractToolLines(callMessage).join("\n");
expect(callLines).toContain("[[tool]] functions.exec (call-1)");
expect(callLines).toContain("\"command\": \"echo hi\"");
const resultLines = extractToolLines(resultMessage).join("\n");
expect(resultLines).toContain("[[tool-result]] functions.exec (call-1)");
expect(resultLines).toContain("ok");
expect(resultLines).toContain("hi");
});
it("does not treat normal messages as UI metadata", () => {
const built = buildAgentInstruction({
message: "hello",
});
expect(isUiMetadataPrefix(built)).toBe(false);
expect(stripUiMetadata(built)).toContain("hello");
expect(stripUiMetadata(built)).not.toContain("Execution approval policy:");
});
it("strips leading system event blocks from queued session updates", () => {
const raw = `System: [2026-02-12 01:09:16 UTC] Exec failed (mild-she, signal SIGKILL)
[Thu 2026-02-12 01:14 UTC] nope none of those are it. keep looking
[message_id: e050a641-aa32-4950-8083-c3bb7efdfc6d]`;
expect(stripUiMetadata(raw)).toBe("nope none of those are it. keep looking");
});
it("hides internal exec approval auto-resume messages from transcript text", () => {
const raw = `[Tue 2026-02-17 12:52 PST] ${EXEC_APPROVAL_AUTO_RESUME_MARKER}
Continue where you left off and finish the task.`;
expect(stripUiMetadata(raw)).toBe("");
});
it("hides legacy auto-resume messages without internal marker", () => {
const raw = `printf "\\n== Root (/) ==\\n" ls -la /
[Tue 2026-02-17 12:52 PST] The exec approval was granted. Continue where you left off and finish the task.`;
expect(stripUiMetadata(raw)).toBe("");
});
it("normalizes assistant helper text shape", () => {
expect(normalizeAssistantDisplayText("first\r\n\r\n\r\nsecond")).toBe("first\n\nsecond");
expect(normalizeAssistantDisplayText("line one \nline two\t \n")).toBe("line one\nline two");
expect(normalizeAssistantDisplayText("\n\nalpha\n\n\nbeta\n\n")).toBe("alpha\n\nbeta");
});
});