Files
hermes-agent/web/src/lib/reasoning-markup.test.ts
2026-10-07 11:18:50 -04:00

55 lines
1.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { hasReasoningMarkup, parseReasoningMarkup } from "./reasoning-markup";
describe("reasoning markup parsing", () => {
it("unwraps thinking prose", () => {
expect(parseReasoningMarkup("<thinking>plain prose</thinking>")).toEqual([
{ type: "prose", content: "plain prose" },
]);
});
it("separates prose from action and result segments", () => {
expect(
parseReasoningMarkup(
'<thinking>prose <action>tool_call</action><result>{"ok":true}</result></thinking>',
),
).toEqual([
{ type: "prose", content: "prose " },
{ type: "action", content: "tool_call" },
{ type: "result", content: '{"ok":true}' },
]);
});
it("does not treat unrelated angle-bracket text as reasoning markup", () => {
const content = "Compare <div> and <custom-tag> in prose.";
expect(hasReasoningMarkup(content)).toBe(false);
expect(parseReasoningMarkup(content)).toEqual([
{ type: "prose", content },
]);
});
it("preserves fenced XML and HTML as ordinary markdown content", () => {
const content = [
"```xml",
"<thinking>keep this literal</thinking>",
"<div>example</div>",
"```",
].join("\n");
expect(hasReasoningMarkup(content)).toBe(false);
expect(parseReasoningMarkup(content)).toEqual([
{ type: "prose", content },
]);
});
it("leaves non-matching known tags as plain text", () => {
const content = "before <thinking>unfinished";
expect(hasReasoningMarkup(content)).toBe(false);
expect(parseReasoningMarkup(content)).toEqual([
{ type: "prose", content },
]);
});
});