From 81016bdaeb94bddb2a24914998722975cc25087a Mon Sep 17 00:00:00 2001 From: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com> Date: Sun, 21 Jun 2026 14:05:16 -0300 Subject: [PATCH] feat(pricing): add default pricing for Qwen coder-model on qw provider (#4488) Rebuilt onto release/v3.8.33 (squash-base-stale). Integrated into release/v3.8.33. --- CHANGELOG.md | 1 + src/shared/constants/pricing.ts | 9 ++++++++ tests/unit/catalog-updates-v3x.test.ts | 30 ++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5d58527f1..e7e6802b6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ _In development — bullets added per PR; finalized at release._ - **feat(models): opt-in low-noise `/v1/models` catalog mode** — a new opt-in mode trims the `/v1/models` response to a quieter, lower-noise catalog for clients that choke on or don't need the full provider/model list. ([#4427](https://github.com/diegosouzapw/OmniRoute/pull/4427) — thanks @Rahulsharma0810) - **feat(ui): expose a `targetFormat` selector in the custom-models form** — the custom-models form now lets you pick the upstream target format explicitly, so a custom model can be pinned to the right wire format instead of relying on inference. ([#4475](https://github.com/diegosouzapw/OmniRoute/pull/4475) — thanks @adivekar-utexas) - **feat(providers): expose `gpt-4o` on the built-in GitHub Copilot (`gh`) provider** — GitHub Copilot still serves the original `gpt-4o` chat model via its `/chat/completions` endpoint, but the OmniRoute registry only shipped the GPT-5.x family, so clients that explicitly request `gpt-4o` against `gh` got an unknown-model error. `gpt-4o` is now registered under the `github` provider next to the GPT-5.x lineup (chat/completions, 128k context — no `openai-responses` targetFormat). Ported from [9router#98](https://github.com/decolua/9router/pull/98). (thanks @I3eka) +- **feat(pricing): default pricing for Qwen `coder-model` on the `qw` provider** — the Qwen Coder Free (`qw`) registry already exposed the `coder-model` id (Qwen3.5/3.6 Coder Model) but `DEFAULT_PRICING.qw` was missing the row, so usage tracking reported `$0.00` for that model. The pricing row is now added with the same shape as the sibling `vision-model` tier, restoring non-zero cost tracking. Ported from upstream 9router PR [decolua/9router#156](https://github.com/decolua/9router/pull/156). (thanks @LinearSakana) ### 🐛 Fixed diff --git a/src/shared/constants/pricing.ts b/src/shared/constants/pricing.ts index 61c36148cc..3af7a92b4c 100644 --- a/src/shared/constants/pricing.ts +++ b/src/shared/constants/pricing.ts @@ -425,6 +425,15 @@ export const DEFAULT_PRICING = { reasoning: 9.0, cache_creation: 1.5, }, + // Qwen3.5/3.6 Coder Model — ported from upstream 9router PR #156 (zx07). + // Priced identically to the vision tier per upstream defaults. + "coder-model": { + input: 1.5, + output: 6.0, + cached: 0.75, + reasoning: 9.0, + cache_creation: 1.5, + }, }, // Qoder AI (if) diff --git a/tests/unit/catalog-updates-v3x.test.ts b/tests/unit/catalog-updates-v3x.test.ts index cdcab7b5f2..0597b371b1 100644 --- a/tests/unit/catalog-updates-v3x.test.ts +++ b/tests/unit/catalog-updates-v3x.test.ts @@ -149,3 +149,33 @@ test("Every Codex registry model resolves a non-zero pricing row (alias: cx)", a ); } }); + +test("Every Qwen registry model resolves a non-zero pricing row (alias: qw)", async () => { + const { getPricingForModel } = await import("../../src/shared/constants/pricing.ts"); + const models = getModelsByProviderId("qwen"); + assert.ok(models.length > 0, "qwen must expose models"); + + for (const model of models) { + // Qwen pricing lives under the "qw" alias (its DEFAULT_PRICING key). + const pricing = getPricingForModel("qw", model.id) as { + input?: number; + output?: number; + } | null; + assert.ok(pricing, `qw pricing must include qwen model "${model.id}"`); + assert.equal( + typeof pricing?.input === "number" && typeof pricing?.output === "number", + true, + `qw pricing for "${model.id}" must have numeric input/output` + ); + } + + // Regression guard: the "coder-model" id (Qwen3.5/3.6 Coder Model, ported from + // upstream 9router PR #156) must be priced like the other Qwen coder tier. + const coderModel = getPricingForModel("qw", "coder-model") as { + input: number; + output: number; + } | null; + assert.ok(coderModel, "qw pricing must include coder-model"); + assert.equal(typeof coderModel?.input, "number"); + assert.equal(typeof coderModel?.output, "number"); +});