Files
OmniRoute/tests/unit/responsesanitizer-reasoning-split.test.ts
Diego Rodrigues de Sa e Souza 6f364f9021 refactor(sse): extract reasoning-tag detection/extraction from responseSanitizer.ts (#5734)
responseSanitizer.ts (1133 lines, frozen-baselined) mixes reasoning-tag
detection/extraction with response/usage/streaming sanitization. Extract the
cohesive, ZERO-IMPORT reasoning block verbatim into a self-contained leaf:

  - responseSanitizer/reasoning.ts (143)  the reasoning regex consts +
    collapseExcessiveNewlines, cleanReasoningFragment,
    splitClosingOnlyReasoningPrefix, movePrefixBeforeContentTagToThinking,
    extractThinkingFromContent, normalizeReasoningRouteId,
    isAntigravityReasoningRoute, isTextualReasoningTagNativeRoute,
    shouldParseTextualReasoningTags

Host responseSanitizer.ts: 1133 -> 1003. The block's helpers only call each
other, so the leaf has ZERO imports — it cannot import the host (check:cycles
clean). The host imports back collapseExcessiveNewlines (6 call sites) +
extractThinkingFromContent, and re-exports the two public symbols
(extractThinkingFromContent, shouldParseTextualReasoningTags) — the public API
stays IDENTICAL (7 exports). Bodies moved byte-identical; two long declarations
(REASONING_TAG_FRAGMENT_REGEX, movePrefixBeforeContentTagToThinking signature)
were line-wrapped by prettier once the 'export' prefix pushed them past 100
cols (token-identical).

Behavior-preserving: 47 existing consumer tests stay green (response-sanitizer
36, strip-reasoning-header 8, textual-toolcall-false-positive 3); new
tests/unit/responsesanitizer-reasoning-split.test.ts (11 assertions)
characterizes extractThinkingFromContent + shouldParseTextualReasoningTags and
guards the public API.

Refs #3501.
2026-06-30 22:46:20 -03:00

82 lines
3.5 KiB
TypeScript

/**
* Characterization + API-surface test: responseSanitizer.ts god-file decomposition.
*
* The reasoning-tag detection/extraction block (regexes + extraction helpers +
* route classification) was extracted verbatim from
* open-sse/handlers/responseSanitizer.ts into the ZERO-IMPORT, self-contained
* leaf open-sse/handlers/responseSanitizer/reasoning.ts. The response/usage/
* streaming sanitization stays in the host.
*
* Verifies that:
* 1. extractThinkingFromContent / shouldParseTextualReasoningTags behave.
* 2. The host still exposes the FULL public API (7 names; the two reasoning
* functions are now re-exported from the leaf).
* 3. The reasoning leaf exports its public pieces directly.
*
* Deeper sanitization behaviour is covered by the existing response-sanitizer /
* strip-reasoning-header suites; this pins the extraction boundary.
*/
import { describe, it } from "node:test";
import assert from "node:assert/strict";
import {
extractThinkingFromContent,
shouldParseTextualReasoningTags,
} from "../../open-sse/handlers/responseSanitizer/reasoning.ts";
describe("responseSanitizer/reasoning — extractThinkingFromContent", () => {
it("leaves tag-free content untouched (thinking = null)", () => {
const out = extractThinkingFromContent("just an answer");
assert.equal(out.content, "just an answer");
assert.equal(out.thinking, null);
});
it("splits a <think>…</think> prefix into thinking + content", () => {
const out = extractThinkingFromContent("<think>reasoning here</think>final answer");
assert.ok(out.thinking && out.thinking.includes("reasoning here"), "thinking captured");
assert.ok(out.content.includes("final answer"), "content kept");
assert.ok(!out.content.includes("<think>"), "think tag stripped from content");
});
});
describe("responseSanitizer/reasoning — shouldParseTextualReasoningTags", () => {
it("returns a boolean; false for a generic non-textual-reasoning route", () => {
const r = shouldParseTextualReasoningTags("openai", "gpt-4");
assert.equal(typeof r, "boolean");
assert.equal(r, false);
});
it("returns false when provider/model are missing", () => {
assert.equal(shouldParseTextualReasoningTags(undefined, undefined), false);
});
});
// ── host public API surface ──────────────────────────────────────────────────
const host = await import("../../open-sse/handlers/responseSanitizer.ts");
describe("responseSanitizer.ts public API surface (7 names)", () => {
const expectedFns = [
"extractThinkingFromContent", // re-exported from leaf
"shouldParseTextualReasoningTags", // re-exported from leaf
"sanitizeOpenAIResponse",
"sanitizeResponsesApiResponse",
"sanitizeStreamingChunk",
];
for (const name of expectedFns) {
it(`exposes ${name} as a function`, () => {
assert.equal(typeof host[name], "function", `${name} must be a function on the host`);
});
}
it("keeps the OMIT_STREAMING_CHUNK_MARKER constant", () => {
assert.equal(typeof host.OMIT_STREAMING_CHUNK_MARKER, "string");
});
});
describe("reasoning.ts exports its public pieces directly", () => {
it("the re-exported reasoning helpers are functions on the leaf", async () => {
const r = await import("../../open-sse/handlers/responseSanitizer/reasoning.ts");
assert.equal(typeof r.extractThinkingFromContent, "function");
assert.equal(typeof r.shouldParseTextualReasoningTags, "function");
});
});