Files
OmniRoute/tests/unit/reasoning-fields-placeholder-strip.test.ts
Praveen K Palaniswamy 65e81158ab fix(ollama): route models by advertised capability (#11088)
Landed with the design call resolved per the owner's pick — **option 1**: the synced store is now endpoint-agnostic (persistDiscoveredModels and managedModelImport no longer drop non-chat models at write time), and chat selectability moved to read time (auto-pool expansion in autoStrategy applies filterChatSelectableModels; the models-route projection already had its chatOnly filter). Your discovery test now passes end-to-end (3/3): /api/show capabilities persist per connection and image/embedding requests route through the advertising host.

Reconciliation notes: conflicted areas merged onto the current tip (adobe discovery import, requestedModel preflight signature, resolvedProvider fast-path coexists with the synced-route override — explicit resolution wins); carried base-red drains (#10055 memoization, #11071 test variants) dropped as already-landed; the managed-model-import exclusion test was propagated to the new contract (image/video models persist; the read filter still hides them from chat pickers — pinned by a new assertion). Full battery: 205/206 focused (the one red is a confirmed periodic-timer timing flake on the loaded devbox — 20/20 isolated), autoCombo vitest 30/30, combo suites 46/46, gates + typecheck clean.

Thank you @yourspraveen — the capability probe + routing design was right; it just needed the store contract opened up. Fixes #11087.
2026-08-23 11:45:01 -03:00

117 lines
4.7 KiB
TypeScript

/**
* tests/unit/reasoning-fields-placeholder-strip.test.ts
*
* copyOpenAICompatibleReasoningFields() must never forward the internal
* reasoning-replay placeholder (NON_ANTHROPIC_THINKING_PLACEHOLDER =
* "(prior reasoning summary unavailable)") to clients — it is request
* scaffolding, and models echo it as their own reasoning (#8081, #9765).
* Previously only reasoning_content / reasoning were stripped; non-standard
* fields (reasoning_text, thinking, thought) and reasoning_details items
* passed through raw, leaking the sentinel on providers that use them
* (e.g. Venice).
*/
import test from "node:test";
import assert from "node:assert/strict";
import { NON_ANTHROPIC_THINKING_PLACEHOLDER } from "../../open-sse/utils/reasoningPlaceholder.ts";
import { copyOpenAICompatibleReasoningFields } from "../../open-sse/utils/reasoningFields.ts";
function copy(source: Record<string, unknown>): Record<string, unknown> {
const target: Record<string, unknown> = {};
copyOpenAICompatibleReasoningFields(source, target);
return target;
}
test("real reasoning_content is preserved verbatim", () => {
const target = copy({ reasoning_content: "Let me think carefully." });
assert.equal(target.reasoning_content, "Let me think carefully.");
});
test("reasoning_content that is exactly the placeholder is dropped", () => {
const target = copy({ reasoning_content: NON_ANTHROPIC_THINKING_PLACEHOLDER });
assert.equal("reasoning_content" in target, false);
});
test("reasoning alias that is exactly the placeholder is dropped", () => {
const target = copy({ reasoning: NON_ANTHROPIC_THINKING_PLACEHOLDER });
assert.equal("reasoning" in target, false);
});
test("reasoning_text that is exactly the placeholder is dropped (Venice path, #9765)", () => {
const target = copy({ reasoning_text: NON_ANTHROPIC_THINKING_PLACEHOLDER });
assert.equal("reasoning_text" in target, false);
});
test("thinking that is exactly the placeholder is dropped", () => {
const target = copy({ thinking: NON_ANTHROPIC_THINKING_PLACEHOLDER });
assert.equal("thinking" in target, false);
});
test("thought that is exactly the placeholder is dropped", () => {
const target = copy({ thought: NON_ANTHROPIC_THINKING_PLACEHOLDER });
assert.equal("thought" in target, false);
});
test("placeholder embedded in otherwise real reasoning_text is stripped in place", () => {
const target = copy({
reasoning_text: `First thought. ${NON_ANTHROPIC_THINKING_PLACEHOLDER} Second thought.`,
});
assert.equal(target.reasoning_text, "First thought. Second thought.");
});
test("no mirrored reasoning_content is emitted when the only signal is the placeholder", () => {
const target = copy({ reasoning_text: NON_ANTHROPIC_THINKING_PLACEHOLDER });
assert.equal("reasoning_content" in target, false);
assert.equal("reasoning_text" in target, false);
});
test("all-placeholder reasoning_details are dropped entirely", () => {
const target = copy({
reasoning_details: [
{ type: "reasoning.text", text: NON_ANTHROPIC_THINKING_PLACEHOLDER },
{ type: "thinking", content: ` ${NON_ANTHROPIC_THINKING_PLACEHOLDER} ` },
],
});
assert.equal("reasoning_details" in target, false);
assert.equal("reasoning_content" in target, false);
});
test("mixed reasoning_details keep real text and drop only placeholder items", () => {
const target = copy({
reasoning_details: [
{ type: "reasoning.text", text: "real first step " },
{ type: "thinking", content: NON_ANTHROPIC_THINKING_PLACEHOLDER },
{ type: "reasoning.text", text: "real second step" },
],
});
assert.deepEqual(target.reasoning_details, [
{ type: "reasoning.text", text: "real first step " },
{ type: "reasoning.text", text: "real second step" },
]);
});
test("placeholder inside a reasoning_details text item is stripped in place", () => {
const target = copy({
reasoning_details: [
{ type: "reasoning.text", text: `real ${NON_ANTHROPIC_THINKING_PLACEHOLDER} tail` },
],
});
assert.deepEqual(target.reasoning_details, [{ type: "reasoning.text", text: "real tail" }]);
});
test("real reasoning_details still mirror into reasoning_content for readable clients", () => {
const target = copy({
reasoning_details: [{ type: "reasoning.text", text: "real reasoning here" }],
});
assert.equal(target.reasoning_content, "real reasoning here");
assert.deepEqual(target.reasoning_details, [
{ type: "reasoning.text", text: "real reasoning here" },
]);
});
test("non-text reasoning_details (e.g. reasoning.encrypted) survive untouched", () => {
const target = copy({
reasoning_details: [{ type: "reasoning.encrypted", data: "sig" }],
});
assert.deepEqual(target.reasoning_details, [{ type: "reasoning.encrypted", data: "sig" }]);
});