diff --git a/open-sse/config/providerModels.js b/open-sse/config/providerModels.js index 4d7c6747..e3691e74 100644 --- a/open-sse/config/providerModels.js +++ b/open-sse/config/providerModels.js @@ -153,6 +153,7 @@ export const PROVIDER_MODELS = { { id: "lite", name: "Qoder Lite" }, // Frontier models — pin a specific backing model { id: "qmodel", name: "Qwen 3.6 Plus (Qoder)" }, + { id: "qmodel_latest", name: "Qoder Qwen 3.7 Max" }, { id: "dmodel", name: "DeepSeek V4 Pro (Qoder)" }, { id: "dfmodel", name: "DeepSeek V4 Flash (Qoder)" }, { id: "gm51model", name: "GLM 5.1 (Qoder)" }, diff --git a/open-sse/executors/qoder.js b/open-sse/executors/qoder.js index aff99cfd..3be1f00f 100644 --- a/open-sse/executors/qoder.js +++ b/open-sse/executors/qoder.js @@ -12,8 +12,8 @@ * - The request shape Qoder expects is non-trivial (chat_context with * mirrored modelConfig, business block with stable IDs, system text * hoisted out of the messages array). All ported from the reference. - * - Model identifier is one of the canonical 11 keys (auto / ultimate / - * performance / efficient / lite + 6 frontier "*model" ids); the + * - Model identifier is one of the canonical Qoder keys (auto / ultimate / + * performance / efficient / lite + frontier "*model" ids); the * translator layer feeds us "qoder/" so we strip the prefix. * - Per-model `model_config` is fetched live from /algo/api/v2/model/list * and cached. Sending the wrong block silently downgrades to a diff --git a/src/lib/qoder/constants.js b/src/lib/qoder/constants.js index 54b51549..1d9ce303 100644 --- a/src/lib/qoder/constants.js +++ b/src/lib/qoder/constants.js @@ -46,6 +46,7 @@ export const QODER_MODEL_MAP = { lite: "lite", // Frontier models qmodel: "qmodel", + qmodel_latest: "qmodel_latest", dmodel: "dmodel", dfmodel: "dfmodel", gm51model: "gm51model", diff --git a/tests/unit/qoder.test.js b/tests/unit/qoder.test.js index fc12be20..fc5f20a1 100644 --- a/tests/unit/qoder.test.js +++ b/tests/unit/qoder.test.js @@ -15,7 +15,12 @@ import crypto from "crypto"; import { qoderEncodeBody } from "../../src/lib/qoder/encoding.js"; import { buildCosyHeaders } from "../../src/lib/qoder/cosy.js"; import { QoderService } from "../../src/lib/oauth/services/qoder.js"; -import { QODER_CHAT_URL_ENCODED, QODER_MODEL_LIST_URL } from "../../src/lib/qoder/constants.js"; +import { + QODER_CHAT_URL_ENCODED, + QODER_MODEL_LIST_URL, + QODER_MODEL_MAP, +} from "../../src/lib/qoder/constants.js"; +import { PROVIDER_MODELS } from "../../open-sse/config/providerModels.js"; import { __test__ as qoderExecutorInternals } from "../../open-sse/executors/qoder.js"; // Convenience aliases — tests were originally written against module-level @@ -25,6 +30,16 @@ const generatePkcePair = () => new QoderService().generatePkcePair(); const initiateDeviceFlow = () => new QoderService().initiateDeviceFlow(); const parseExpiry = QoderService.parseExpiry; +describe("QODER_MODEL_MAP", () => { + it("allows Qoder's latest model key", () => { + expect(QODER_MODEL_MAP.qmodel_latest).toBe("qmodel_latest"); + }); + + it("exposes Qoder's latest model in the static provider catalog", () => { + expect(PROVIDER_MODELS.qd.some((model) => model.id === "qmodel_latest")).toBe(true); + }); +}); + describe("qoderEncodeBody", () => { it("preserves base64 length (input length divisible by 3)", () => { const input = Buffer.from("abcdef", "utf8"); // 6 bytes → 8 base64 chars