Files
OmniRoute/tests/unit/combo/pin-recovery.test.ts
AmirHossein Rezaei 1c2143182c fix(combo): fail open when strict context filter empties unknown-only pools (#8786) (#8798)
Strict contextFilterMode excluded every target whose context limit was missing
from the capability catalog, so otherwise-executable combos returned 404
no_executable_targets. Restore unknown-context targets when no known-good
survivor remains, surface context_requirements_exhausted from targetResolution,
and keep the empty-pool payload in pinRecovery after the #8592 split.
2026-07-27 22:37:48 -03:00

108 lines
4.4 KiB
TypeScript

// tests/unit/combo/pin-recovery.test.ts
// Direct unit coverage for open-sse/services/combo/pinRecovery.ts — extracted from
// combo.ts (file-size cap) so it needs its own direct test rather than relying only
// on indirect coverage through handleComboChat integration tests.
import test from "node:test";
import assert from "node:assert/strict";
import {
buildRecoveryHint,
buildNoUpstreamResponseDiagnostics,
buildEmptyComboTargetsPayload,
} from "../../../open-sse/services/combo/pinRecovery.ts";
test("buildRecoveryHint: reasoning_budget_exhausted maps to switch-combo", () => {
const hint = buildRecoveryHint("reasoning_budget_exhausted");
assert.equal(hint.action, "switch-combo");
assert.match(hint.next_step, /Increase max_tokens/);
});
test("buildRecoveryHint: max_attempts_exceeded maps to try-auto", () => {
const hint = buildRecoveryHint("max_attempts_exceeded");
assert.equal(hint.action, "try-auto");
assert.match(hint.next_step, /model: auto/);
});
test("buildRecoveryHint: all_accounts_inactive maps to switch-combo with dashboard hint", () => {
const hint = buildRecoveryHint("all_accounts_inactive");
assert.equal(hint.action, "switch-combo");
assert.match(hint.next_step, /dashboard\/providers/);
});
test("buildRecoveryHint: all_models_failed includes retry_after_seconds when positive", () => {
const hint = buildRecoveryHint("all_models_failed", 30);
assert.equal(hint.action, "try-auto");
assert.equal(hint.retry_after_seconds, 30);
});
test("buildRecoveryHint: all_models_failed omits retry_after_seconds when undefined", () => {
const hint = buildRecoveryHint("all_models_failed");
assert.equal(hint.action, "try-auto");
assert.equal("retry_after_seconds" in hint, false);
});
test("buildRecoveryHint: all_models_failed omits retry_after_seconds when zero or negative", () => {
assert.equal("retry_after_seconds" in buildRecoveryHint("all_models_failed", 0), false);
assert.equal("retry_after_seconds" in buildRecoveryHint("all_models_failed", -5), false);
});
test("buildRecoveryHint: no_executable_targets maps to switch-combo", () => {
const hint = buildRecoveryHint("no_executable_targets");
assert.equal(hint.action, "switch-combo");
assert.match(hint.next_step, /no executable targets/);
});
test("buildRecoveryHint: context_requirements_exhausted maps to switch-combo (#8786)", () => {
const hint = buildRecoveryHint("context_requirements_exhausted");
assert.equal(hint.action, "switch-combo");
assert.match(hint.next_step, /minContextWindow|contextFilterMode|lenient/i);
});
test("buildRecoveryHint: unknown terminalReason falls back to retry", () => {
const hint = buildRecoveryHint("some_unrecognized_reason");
assert.equal(hint.action, "retry");
assert.match(hint.next_step, /transiently/);
});
test("buildNoUpstreamResponseDiagnostics: builds a minimal diagnostics payload from poolSize", () => {
const diag = buildNoUpstreamResponseDiagnostics(4);
assert.deepEqual(diag, {
poolSize: 4,
attempted: 0,
excluded: [],
attemptOrder: [],
terminalReason: "no_upstream_response",
});
});
test("buildNoUpstreamResponseDiagnostics: zero poolSize is passed through as-is", () => {
const diag = buildNoUpstreamResponseDiagnostics(0);
assert.equal(diag.poolSize, 0);
assert.equal(diag.terminalReason, "no_upstream_response");
});
test("buildEmptyComboTargetsPayload: pre-filter pool → context_requirements_exhausted (#8786)", () => {
const { message, diagnostics } = buildEmptyComboTargetsPayload(
[
{ provider: "openai", modelStr: "gpt-4o" },
{ provider: "custom", modelStr: "tiny" },
],
500000
);
assert.match(message, /context requirements filtering/);
assert.match(message, /minContextWindow: 500000/);
assert.equal(diagnostics.terminalReason, "context_requirements_exhausted");
assert.equal(diagnostics.poolSize, 2);
assert.equal(diagnostics.excluded?.length, 2);
assert.equal(diagnostics.excluded?.[0]?.reason, "context_requirements");
assert.equal(diagnostics.recovery?.action, "switch-combo");
});
test("buildEmptyComboTargetsPayload: empty pre-filter pool → generic no_executable_targets", () => {
const { message, diagnostics } = buildEmptyComboTargetsPayload([], 128000);
assert.equal(message, "Combo has no executable targets");
assert.equal(diagnostics.terminalReason, "no_executable_targets");
assert.equal(diagnostics.poolSize, 0);
assert.deepEqual(diagnostics.excluded, []);
});