Files
OmniRoute/tests/unit/strict-zero-cost-exclusion-reason.test.ts
Dizzle 2f33f2c20d feat(routing): report why the zero-cost guard excluded a candidate (#12319)
With freeAccessPolicy: "strict" the read-only candidate listing silently dropped rows, so an operator could not tell "no free allowance left" from "the quota fetcher is broken" — in a listing whose own module header promises a candidate the routing path would skip "is never dropped". #9133 settled the same question for the resilience filter via a skip opt-out; the zero-cost guard never got one.

It gets it now: the guard is disabled for the inspector build exactly as the resilience filter already is, and every candidate carries freeAccessExclusion — null when satisfied, otherwise one of seven named reasons. The last three (exhausted, state-unknown, no-connection) are the point: they used to look identical because the row just disappeared. STRICT_ZERO_COST.md documents what each asks the operator to do.

Dispatch is untouched and a test pins that. The three existing guard suites were not modified — their 31 cases are the net and still pass. excludeTosAvoid still drops candidates without a reason; documented as a separate question rather than widened into here.

Verified in a combined batch worktree: 174/174 focused tests across all 11 PRs of this batch, typecheck:core clean, complexity 2706/3218, cognitive-complexity 1221/1437, check:cycles and check:docs-counts green.

Thanks @maxmad64bis — the reason table and the honest note about the order change (freshness before status) made this easy to review.
2026-09-01 11:49:56 -03:00

230 lines
7.9 KiB
TypeScript

import assert from "node:assert/strict";
import test from "node:test";
import {
classifyConnectionState,
classifyStrictZeroCostCandidate,
evaluateCandidateConnections,
type FreeAccessState,
type StrictZeroCostCandidate,
} from "../../open-sse/services/autoCombo/strictZeroCostFilter.ts";
import type { FreeModelBudget } from "../../open-sse/config/freeModelCatalog.ts";
const NOW = 10_000_000;
const OPTS = { minRemainingAllowance: 1, maxStateAgeMs: 60_000, now: () => NOW };
function entry(overrides: Partial<FreeModelBudget> = {}): FreeModelBudget {
return {
provider: "p",
model: "m",
freeType: "recurring-monthly",
hardStopGuaranteed: true,
...overrides,
} as FreeModelBudget;
}
function state(overrides: Partial<FreeAccessState> = {}): FreeAccessState {
return {
status: "SAFE",
remainingFreeAllowance: 90,
resetAt: null,
checkedAt: new Date(NOW).toISOString(),
...overrides,
};
}
const candidate = (overrides: Partial<StrictZeroCostCandidate> = {}): StrictZeroCostCandidate => ({
provider: "p",
model: "m",
connectionId: "c1",
...overrides,
});
const classify = (
c: StrictZeroCostCandidate,
e: FreeModelBudget | undefined,
resolve: (provider: string, connectionId: string) => FreeAccessState | undefined
) => classifyStrictZeroCostCandidate(c, e, resolve, OPTS);
// --- one connection at a time ---------------------------------------------
test("a fresh, funded reading is safe", () => {
assert.equal(
classifyConnectionState("p", "c1", () => state(), OPTS),
"safe"
);
});
test("no reading at all is unknown — the quota lookup never ran for this pair", () => {
assert.equal(
classifyConnectionState("p", "c1", () => undefined, OPTS),
"state-unknown"
);
});
test("an exhausted allowance is exhausted, not unknown", () => {
const drained = state({ status: "EXHAUSTED", remainingFreeAllowance: 0 });
assert.equal(
classifyConnectionState("p", "c1", () => drained, OPTS),
"exhausted"
);
});
test("a funded reading at or below the threshold is exhausted", () => {
assert.equal(
classifyConnectionState("p", "c1", () => state({ remainingFreeAllowance: 1 }), OPTS),
"exhausted"
);
});
test("a reading older than the allowed age is unknown, never exhausted", () => {
const stale = state({ checkedAt: new Date(NOW - 60_001).toISOString() });
assert.equal(
classifyConnectionState("p", "c1", () => stale, OPTS),
"state-unknown"
);
});
test("a stale EXHAUSTED reading is unknown too — freshness is checked first", () => {
const staleDrained = state({
status: "EXHAUSTED",
remainingFreeAllowance: 0,
checkedAt: new Date(NOW - 60_001).toISOString(),
});
assert.equal(
classifyConnectionState("p", "c1", () => staleDrained, OPTS),
"state-unknown"
);
});
test("an allowance the provider does not report numerically is unknown", () => {
assert.equal(
classifyConnectionState("p", "c1", () => state({ remainingFreeAllowance: null }), OPTS),
"state-unknown"
);
});
test("an unparseable timestamp is unknown", () => {
assert.equal(
classifyConnectionState("p", "c1", () => state({ checkedAt: "not a date" }), OPTS),
"state-unknown"
);
});
// --- whole candidate -------------------------------------------------------
test("a model absent from the catalog is not-in-catalog", () => {
assert.equal(classify(candidate(), undefined, () => state()).outcome, "not-in-catalog");
});
test("a catalogued model whose regime is not free is regime-not-free", () => {
const paid = entry({ freeType: "discontinued" as FreeModelBudget["freeType"] });
assert.equal(classify(candidate(), paid, () => state()).outcome, "regime-not-free");
});
test("a free regime without a documented hard stop is no-hard-stop", () => {
const soft = entry({ hardStopGuaranteed: undefined });
assert.equal(classify(candidate(), soft, () => state()).outcome, "no-hard-stop");
});
test("a genuine keyless candidate is safe with no live check", () => {
const keyless = entry({ freeType: "keyless" as FreeModelBudget["freeType"] });
const verdict = classify(candidate({ connectionId: "noauth" }), keyless, () => undefined);
assert.equal(verdict.outcome, "safe");
});
test("a no-auth candidate on a non-keyless entry is contradictory-noauth", () => {
const verdict = classify(candidate({ connectionId: "noauth" }), entry(), () => state());
assert.equal(verdict.outcome, "contradictory-noauth");
});
test("a funded candidate is safe and names the connection", () => {
const verdict = classify(candidate(), entry(), () => state());
assert.equal(verdict.outcome, "safe");
assert.deepEqual(verdict.outcome === "safe" ? verdict.safeConnectionIds : null, ["c1"]);
});
test("exhausted wins over unknown when a candidate spans several accounts", () => {
// Order must not decide the reason: an observed exhaustion is a fact, a
// missing reading is the absence of one, and the operator needs the fact.
const multi = candidate({ connectionId: null, allowedConnectionIds: ["unknown-one", "drained"] });
const resolve = (_p: string, id: string) =>
id === "drained" ? state({ status: "EXHAUSTED", remainingFreeAllowance: 0 }) : undefined;
assert.equal(classify(multi, entry(), resolve).outcome, "exhausted");
const reversed = candidate({
connectionId: null,
allowedConnectionIds: ["drained", "unknown-one"],
});
assert.equal(classify(reversed, entry(), resolve).outcome, "exhausted");
});
test("one safe account among several is still safe, and only it is named", () => {
const multi = candidate({ connectionId: null, allowedConnectionIds: ["drained", "good"] });
const resolve = (_p: string, id: string) =>
id === "good" ? state() : state({ status: "EXHAUSTED", remainingFreeAllowance: 0 });
const verdict = classify(multi, entry(), resolve);
assert.equal(verdict.outcome, "safe");
assert.deepEqual(verdict.outcome === "safe" ? verdict.safeConnectionIds : null, ["good"]);
});
// --- the contract the pool filter depends on, unchanged --------------------
// These mirror what `tests/unit/autoCombo/strict-zero-cost-*.test.ts` assert.
// Those files live outside every runner glob in package.json and vitest.config.ts,
// so they never execute; this block keeps the same guarantees somewhere that runs.
test("evaluateCandidateConnections still answers with connection ids", () => {
assert.deepEqual(
evaluateCandidateConnections(candidate(), entry(), () => state(), OPTS),
["c1"]
);
});
test("evaluateCandidateConnections still answers empty for every exclusion", () => {
const cases: Array<[string, FreeModelBudget | undefined, () => FreeAccessState | undefined]> = [
["not in catalog", undefined, () => state()],
[
"regime not free",
entry({ freeType: "discontinued" as FreeModelBudget["freeType"] }),
() => state(),
],
["no hard stop", entry({ hardStopGuaranteed: undefined }), () => state()],
["no reading", entry(), () => undefined],
["exhausted", entry(), () => state({ status: "EXHAUSTED", remainingFreeAllowance: 0 })],
];
for (const [label, budgetEntry, resolve] of cases) {
assert.deepEqual(
evaluateCandidateConnections(candidate(), budgetEntry, resolve, OPTS),
[],
`"${label}" must still exclude`
);
}
});
test("a candidate with no account at all says so, rather than blaming the quota lookup", () => {
let lookups = 0;
const verdict = classifyStrictZeroCostCandidate(
candidate({ connectionId: null, allowedConnectionIds: [] }),
entry(),
() => {
lookups += 1;
return state();
},
OPTS
);
assert.equal(verdict.outcome, "no-connection");
assert.equal(lookups, 0, "nothing should have been looked up — there was nothing to look up");
});
test("no-connection still excludes, exactly as before", () => {
assert.deepEqual(
evaluateCandidateConnections(
candidate({ connectionId: null, allowedConnectionIds: [] }),
entry(),
() => state(),
OPTS
),
[]
);
});