First Release of Claw3D (#11)
Co-authored-by: iamlukethedev <iamlukethedev@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
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");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user