fix(providers): add claude-sonnet-5 to Kiro model catalog (#5796)

Integrated into release/v3.8.43
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-07-01 21:50:13 -03:00
committed by GitHub
parent 12ac520014
commit eadd7338f6
3 changed files with 38 additions and 0 deletions

View File

@@ -32,6 +32,8 @@
### 🔧 Bug Fixes
- **providers (Kiro — Claude Sonnet 5):** the Kiro provider's model catalog was missing `claude-sonnet-5`, so the model could not be selected or routed even on accounts that already had access to it ("claude-sonnet-5 is not supported"). Added the model to the Kiro registry (`open-sse/config/providers/registry/kiro/index.ts`) as a 1M-context / 128K-output Claude model, mirroring the existing Claude entries; the registry `models[]` feeds both the model selector and the live CodeWhisperer `ListAvailableModels` fallback, so the model is now selectable and routable. Regression guard: `tests/unit/kiro-claude-sonnet-5-2267.test.ts`. (thanks [@openbioinfo](https://github.com/openbioinfo))
- **settings (model aliases — self-heal after restart):** the Settings → Routing page showed "No exact-match aliases configured" after a server restart even though the aliases were persisted in the DB. Aliases are held in a module-local `_customAliases` map in `modelDeprecation.ts` that the boot path hydrates, but Next.js compiles the app-route module graph separately from the startup graph (the same webpack chunk-splitting class as #5312), so the `GET /api/settings/model-aliases` handler read a different, un-hydrated copy. The handler now self-heals: when its in-memory alias map is empty it reads `settings.modelAliases` from the DB (via the existing `getSettings()` db module — no raw SQL in the route) and repopulates the map, so the UI reflects the persisted aliases on the first GET after a restart. Follow-up: the root cause is now also fixed — the `_customAliases` store in `modelDeprecation.ts` is backed by `globalThis` (key `__omniroute_customAliases__`), so the startup and app-route module graphs share **one** store and the route reads the boot-hydrated aliases directly (the DB self-heal remains as a harmless fallback), mirroring the same `globalThis` singleton pattern already applied to `thinkingBudget.ts`/`backgroundTaskDetector.ts` (#5312). Regression guards: `tests/unit/model-aliases-settings-route-selfheal.test.ts` + `tests/unit/model-aliases-globalthis-5777.test.ts`. ([#5777](https://github.com/diegosouzapw/OmniRoute/pull/5777) — thanks [@jleonar2](https://github.com/jleonar2))
- **providers (grok-cli token auto-refresh):** grok-cli OAuth tokens were never proactively refreshed before their real expiry. `mapTokens` hardcoded `expiresIn: 21600` (6 h) regardless of the token's actual lifetime, so the persisted `expiresAt` was always "now + 6 h" and the proactive `tokenHealthCheck` sweep (refresh when `expiresAt - now < 5 min`) fired 6 h after import instead of shortly before the token really expired. `mapTokens` now computes `expiresIn` from the authoritative `expires_at` field in `~/.grok/auth.json` (ISO → epoch-seconds) with a fallback to the JWT `exp` claim (payload-only decode, no signature trust); the hardcoded `21600` is kept only when neither is present. An already-expired token (real `expires_at`/`exp` in the past) is now clamped to a positive `expiresIn` via `Math.max(1, …)`, so the import route stores a near-future `expiresAt` and AutoCombo refreshes the connection instead of reading a past date and excluding it outright. Regression guards: 5 cases in `tests/unit/grok-cli-oauth.test.ts` (JWT `exp`, JSON `expires_at`, the `21600` fallback, and the two expired-token clamps). ([#5775](https://github.com/diegosouzapw/OmniRoute/pull/5775) — thanks [@Chewji9875](https://github.com/Chewji9875))

View File

@@ -41,6 +41,12 @@ export const kiroProvider: RegistryEntry = {
contextLength: 1000000,
maxOutputTokens: 128000,
},
{
id: "claude-sonnet-5",
name: "Claude Sonnet 5",
contextLength: 1000000,
maxOutputTokens: 128000,
},
{
id: "claude-sonnet-4.6",
name: "Claude Sonnet 4.6",

View File

@@ -0,0 +1,30 @@
import test from "node:test";
import assert from "node:assert/strict";
import { kiroProvider } from "../../open-sse/config/providers/registry/kiro/index.ts";
// Regression for the port of decolua/9router#2267 ("claude-sonnet-5 is not supported").
//
// The Kiro provider's OAuth model catalog lives in `registry/kiro/index.ts` `models[]`.
// That list is both the model selector's source and the fallback for the live
// CodeWhisperer ListAvailableModels fetch (`kiroModels.ts::toFallbackResult`). Because
// `claude-sonnet-5` — a real, shipping Anthropic model already served by Kiro — was
// missing from it, the model could not be selected or routed on the Kiro provider even
// though the account had access. The fix adds the single model entry (mirroring the
// existing Claude entries), with the 1M-context / 128K-output capability Kiro serves it at.
test("kiro registry exposes claude-sonnet-5", () => {
const ids = kiroProvider.models.map((m) => m.id);
assert.ok(
ids.includes("claude-sonnet-5"),
`expected kiro registry to include claude-sonnet-5, got: ${ids.join(", ")}`
);
});
test("kiro claude-sonnet-5 declares the 1M-context / 128K-output capability", () => {
const sonnet5 = kiroProvider.models.find((m) => m.id === "claude-sonnet-5");
assert.ok(sonnet5, "claude-sonnet-5 must be present in the kiro registry");
assert.equal(sonnet5.name, "Claude Sonnet 5");
assert.equal(sonnet5.contextLength, 1000000);
assert.equal(sonnet5.maxOutputTokens, 128000);
});