import assert from "node:assert/strict"; import { describe, it } from "node:test"; import { isValidAssistantModelRoute, isValidLlmModelId, listLlmModels, normalizeLlmModelsPayload, resolveAssistantModel, } from "../../src/lib/llm/models"; import type { LlmConfig } from "../../src/lib/llm/config"; const openAiConfig: LlmConfig = { provider: "openai", baseUrl: "https://llm.example.test/v1", apiKey: "secret", model: "llama3.2", }; describe("normalizeLlmModelsPayload", () => { it("normalizes OpenAI-compatible data arrays", () => { const models = normalizeLlmModelsPayload({ data: [{ id: "qwen2.5-coder" }, { id: "llama3.2" }, { id: "qwen2.5-coder" }], }); assert.deepEqual(models, [ { id: "llama3.2", label: "llama3.2" }, { id: "qwen2.5-coder", label: "qwen2.5-coder" }, ]); }); it("ignores invalid or empty model rows", () => { const models = normalizeLlmModelsPayload({ data: [ { id: "" }, { id: " " }, { id: "bad model" }, { id: " llama3.2 " }, { object: "model" }, ], }); assert.deepEqual(models, []); }); }); describe("isValidLlmModelId", () => { it("accepts common provider model IDs", () => { assert.equal(isValidLlmModelId("llama3.2"), true); assert.equal(isValidLlmModelId("qwen2.5-coder:latest"), true); assert.equal(isValidLlmModelId("hf.co/ginnoir/model-v1"), true); }); it("rejects empty, whitespace, and overlong model IDs", () => { assert.equal(isValidLlmModelId(""), false); assert.equal(isValidLlmModelId("bad model"), false); assert.equal(isValidLlmModelId("x".repeat(129)), false); }); }); describe("isValidAssistantModelRoute", () => { it("accepts the supported route families", () => { assert.equal(isValidAssistantModelRoute("auto"), true); assert.equal(isValidAssistantModelRoute("uncensored"), true); }); it("rejects unsupported or padded route families", () => { assert.equal(isValidAssistantModelRoute("bogus"), false); assert.equal(isValidAssistantModelRoute(" uncensored "), false); }); }); describe("listLlmModels", () => { it("fetches provider models with API key auth when the fallback is advertised", async () => { const requests: Request[] = []; const result = await listLlmModels({ config: openAiConfig, fetchImpl: async (input, init) => { requests.push(new Request(input, init)); return Response.json({ data: [{ id: "qwen2.5-coder" }, { id: "llama3.2" }] }); }, }); assert.equal(requests[0]?.url, "https://llm.example.test/v1/models"); assert.equal(requests[0]?.headers.get("authorization"), "Bearer secret"); assert.deepEqual(result.models, [ { id: "llama3.2", label: "llama3.2" }, { id: "qwen2.5-coder", label: "qwen2.5-coder" }, ]); assert.equal(result.fallbackModel, "llama3.2"); assert.equal(result.degraded, false); }); it("falls back to LLM_MODEL when provider discovery fails", async () => { const result = await listLlmModels({ config: openAiConfig, fetchImpl: async () => new Response("nope", { status: 500 }), }); assert.deepEqual(result.models, [{ id: "llama3.2", label: "llama3.2" }]); assert.equal(result.fallbackModel, "llama3.2"); assert.equal(result.degraded, true); }); it("fetches the typed uncensored catalog when uncensored is the selected route", async () => { const requests: Request[] = []; const result = await listLlmModels({ config: { ...openAiConfig, model: "auto" }, route: "uncensored", fetchImpl: async (input, init) => { requests.push(new Request(input, init)); return Response.json({ data: [ { id: "uncensored" }, { id: "gemma4-uncensored:26b" }, { id: "dolphin-mistral:latest" }, ], }); }, }); assert.equal(requests[0]?.url, "https://llm.example.test/v1/models?type=uncensored"); assert.deepEqual(result.models, [ { id: "dolphin-mistral:latest", label: "dolphin-mistral:latest" }, { id: "gemma4-uncensored:26b", label: "gemma4-uncensored:26b" }, { id: "uncensored", label: "uncensored" }, ]); assert.equal(result.fallbackModel, "uncensored"); assert.equal(result.route, "uncensored"); assert.equal(result.degraded, false); }); it("fetches the default catalog when auto is selected over an uncensored deployment default", async () => { const requests: Request[] = []; const result = await listLlmModels({ config: { ...openAiConfig, model: "uncensored" }, route: "auto", fetchImpl: async (input, init) => { requests.push(new Request(input, init)); return Response.json({ data: [{ id: "auto" }, { id: "qwen3:8b" }], }); }, }); assert.equal(requests[0]?.url, "https://llm.example.test/v1/models"); assert.deepEqual(result.models, [ { id: "auto", label: "auto" }, { id: "qwen3:8b", label: "qwen3:8b" }, ]); assert.equal(result.fallbackModel, "auto"); assert.equal(result.route, "auto"); assert.equal(result.degraded, false); }); it("uses fallback only for mock provider config", async () => { const result = await listLlmModels({ config: { provider: "mock", baseUrl: null, apiKey: null, model: "llama3.2" }, fetchImpl: async () => { throw new Error("fetch should not run for mock config"); }, }); assert.deepEqual(result.models, [{ id: "llama3.2", label: "llama3.2" }]); assert.equal(result.degraded, false); }); }); describe("resolveAssistantModel", () => { it("uses a valid requested model before saved and fallback values", () => { const resolved = resolveAssistantModel({ requestedModel: "qwen2.5-coder", savedModel: "llama3.2", fallbackModel: "llama3.2", models: [ { id: "llama3.2", label: "llama3.2" }, { id: "qwen2.5-coder", label: "qwen2.5-coder" }, ], }); assert.deepEqual(resolved, { ok: true, model: "qwen2.5-coder" }); }); it("rejects invalid requested models", () => { const resolved = resolveAssistantModel({ requestedModel: "bad model", savedModel: null, fallbackModel: "llama3.2", models: [ { id: "llama3.2", label: "llama3.2" }, { id: "bad model", label: "bad model" }, ], }); assert.deepEqual(resolved, { ok: false, model: "llama3.2", error: "Invalid assistant model", }); }); it("rejects empty requested models", () => { const resolved = resolveAssistantModel({ requestedModel: "", savedModel: null, fallbackModel: "llama3.2", models: [{ id: "llama3.2", label: "llama3.2" }], }); assert.deepEqual(resolved, { ok: false, model: "llama3.2", error: "Invalid assistant model", }); }); it("rejects unavailable requested models", () => { const resolved = resolveAssistantModel({ requestedModel: "missing", savedModel: null, fallbackModel: "llama3.2", models: [{ id: "llama3.2", label: "llama3.2" }], }); assert.deepEqual(resolved, { ok: false, model: "llama3.2", error: "Invalid assistant model", }); }); it("silently falls back when a saved model is gone", () => { const resolved = resolveAssistantModel({ requestedModel: null, savedModel: "old-model", fallbackModel: "llama3.2", models: [{ id: "llama3.2", label: "llama3.2" }], }); assert.deepEqual(resolved, { ok: true, model: "llama3.2" }); }); });