Summary
parseTier can return the wrong token-saver tier when knownTiers contains names where one tier is a word-prefix of another hyphenated tier. The fallback parser checks shorter tiers with a word-boundary regex before checking whether the cleaned judge output exactly equals the longer tier.
Code path
src/router/tokenSaver/parseTier.ts:3-20 strips code fences, handles <tier>...</tier>, then falls back to iterating knownTiers.
src/router/tokenSaver/parseTier.ts:13-17 uses \b${tier}\b, which treats - as a word boundary.
src/router/tokenSaver/generateJudgePrompt.ts:25 asks the judge to return <tier>NAME</tier>, but parseTier intentionally accepts non-tagged fallback text.
src/router/config/schema.ts:25-30 defines router.tokenSaver.tiers as user-configured tier names.
Steps to reproduce
On the current main code path, the following minimal call returns the shorter prefix tier:
import { parseTier } from "./src/router/tokenSaver/parseTier.js";
console.log(parseTier("a-a", ["a", "a-a"]));
Actual result:
Expected result:
A practical configuration can hit the same shape with tier names such as fast and fast-pro if the judge returns a bare tier name instead of the preferred tag wrapper.
Expected behavior
When the cleaned judge output is exactly a known tier name, that exact tier should take precedence over word-boundary substring matches.
Actual behavior
The fallback branch iterates knownTiers in order. Because a hyphen is a word boundary, "a-a" matches \ba\b and returns "a" before the parser reaches "a-a".
Existing coverage
I could not find an existing open or closed issue/PR covering this parseTier / token-saver tier-prefix collision.
Suggested fix
One focused fix is to check exact cleaned tier equality before the regex fallback, case-insensitively. Another option is to sort fallback candidates by descending length before applying word-boundary matching.
Suggested tests
parseTier("a-a", ["a", "a-a"]) returns "a-a".
parseTier("<tier>a-a</tier>", ["a", "a-a"]) still returns "a-a".
- A bare output like
"please use a-a" keeps the intended fallback behavior without selecting "a" first.
Submitted with Codex.
Summary
parseTiercan return the wrong token-saver tier whenknownTierscontains names where one tier is a word-prefix of another hyphenated tier. The fallback parser checks shorter tiers with a word-boundary regex before checking whether the cleaned judge output exactly equals the longer tier.Code path
src/router/tokenSaver/parseTier.ts:3-20strips code fences, handles<tier>...</tier>, then falls back to iteratingknownTiers.src/router/tokenSaver/parseTier.ts:13-17uses\b${tier}\b, which treats-as a word boundary.src/router/tokenSaver/generateJudgePrompt.ts:25asks the judge to return<tier>NAME</tier>, butparseTierintentionally accepts non-tagged fallback text.src/router/config/schema.ts:25-30definesrouter.tokenSaver.tiersas user-configured tier names.Steps to reproduce
On the current
maincode path, the following minimal call returns the shorter prefix tier:Actual result:
"a"Expected result:
"a-a"A practical configuration can hit the same shape with tier names such as
fastandfast-proif the judge returns a bare tier name instead of the preferred tag wrapper.Expected behavior
When the cleaned judge output is exactly a known tier name, that exact tier should take precedence over word-boundary substring matches.
Actual behavior
The fallback branch iterates
knownTiersin order. Because a hyphen is a word boundary,"a-a"matches\ba\band returns"a"before the parser reaches"a-a".Existing coverage
I could not find an existing open or closed issue/PR covering this
parseTier/ token-saver tier-prefix collision.Suggested fix
One focused fix is to check exact cleaned tier equality before the regex fallback, case-insensitively. Another option is to sort fallback candidates by descending length before applying word-boundary matching.
Suggested tests
parseTier("a-a", ["a", "a-a"])returns"a-a".parseTier("<tier>a-a</tier>", ["a", "a-a"])still returns"a-a"."please use a-a"keeps the intended fallback behavior without selecting"a"first.Submitted with Codex.