lib/ai-model-config-file.test.ts
Rama main · réplica de lectura del repositorio original.
import { describe, expect, it } from "vitest";
import {
buildModelConfigFile,
diffModelConfig,
MODEL_CONFIG_FILE_FORMAT,
MODEL_CONFIG_FILE_VERSION,
parseModelConfigFile,
} from "@/lib/ai-model-config-file";
/**
* The model configuration file (MIN-829): what one instance exports must
* import into another as the same configuration, a newer file is refused,
* and an import replaces rather than merges.
*/
const STORED = {
assistant_model: "openai/gpt-5-mini",
issue_embedding_model: "google/gemini-embedding-001",
jev_model: "liquid/d1",
assistant_reasoning_level: "high",
byok_default_openai_assistant_model: "gpt-5",
smart_fill_model: null,
};
describe("model configuration file", () => {
it("writes only what is set, under its version", () => {
const file = buildModelConfigFile(STORED, new Date("2026-10-29T00:00:00Z"));
expect(file).toEqual({
format: MODEL_CONFIG_FILE_FORMAT,
version: MODEL_CONFIG_FILE_VERSION,
exportedAt: "2026-10-29T00:00:00.000Z",
tasks: {
assistant_model: { model: "openai/gpt-5-mini" },
issue_embedding_model: { model: "google/gemini-embedding-001" },
jev_model: { model: "liquid/d1" },
},
reasoningLevel: "high",
providerDefaults: { byok_default_openai_assistant_model: "gpt-5" },
});
});
it("imports an export as the same configuration", () => {
const parsed = parseModelConfigFile(JSON.stringify(buildModelConfigFile(STORED)));
expect(parsed.ok).toBe(true);
if (!parsed.ok) return;
expect(diffModelConfig(STORED, parsed.values)).toEqual([]);
expect(parsed.upgraded).toBe(false);
});
it("returns every setting the file leaves out to its default", () => {
const parsed = parseModelConfigFile({
format: MODEL_CONFIG_FILE_FORMAT,
version: MODEL_CONFIG_FILE_VERSION,
tasks: { assistant_model: { model: "openai/gpt-5" } },
});
if (!parsed.ok) throw new Error(parsed.error);
const changes = diffModelConfig(STORED, parsed.values);
expect(changes).toContainEqual({ key: "assistant_model", from: "openai/gpt-5-mini", to: "openai/gpt-5" });
expect(changes).toContainEqual({ key: "jev_model", from: "liquid/d1", to: null });
expect(changes).toContainEqual({ key: "issue_embedding_model", from: "google/gemini-embedding-001", to: null });
});
it("upgrades a version 1 file: categories fill their role, the rest is named (MIN-954)", () => {
const parsed = parseModelConfigFile({
format: MODEL_CONFIG_FILE_FORMAT,
version: 1,
categories: {
assistant: { model: "anthropic/claude-haiku-5.5", suffix: "nitro" },
automations: { model: "openai/gpt-5-mini" },
},
tasks: { brief_model: { model: "openai/gpt-5" }, transcription_model: { model: "openai/whisper-large-v3" } },
recommendedModels: ["openai/gpt-5-mini"],
});
if (!parsed.ok) throw new Error(parsed.error);
expect(parsed.upgraded).toBe(true);
expect(parsed.values).toMatchObject({
assistant_model: "anthropic/claude-haiku-5.5",
transcription_model: "openai/whisper-large-v3",
});
expect(parsed.values).not.toHaveProperty("assistant_model_suffix");
expect(parsed.ignored).toEqual([
"categories.automations",
"tasks.brief_model",
"tasks.assistant_model.suffix",
"recommendedModels",
]);
});
it("refuses a file written by a newer release", () => {
expect(
parseModelConfigFile({ format: MODEL_CONFIG_FILE_FORMAT, version: MODEL_CONFIG_FILE_VERSION + 1 }),
).toEqual({ ok: false, error: "newer_version" });
});
it.each([
["not JSON", "{", "invalid_json"],
["another file", { format: "something-else", version: 1 }, "not_a_model_config"],
["no version", { format: MODEL_CONFIG_FILE_FORMAT }, "not_a_model_config"],
[
"an invalid model id",
{ format: MODEL_CONFIG_FILE_FORMAT, version: 2, tasks: { assistant_model: { model: 42 } } },
"invalid_value",
],
[
"an unknown reasoning level",
{ format: MODEL_CONFIG_FILE_FORMAT, version: 2, reasoningLevel: "extreme" },
"invalid_value",
],
])("refuses %s", (_label, input, error) => {
const parsed = parseModelConfigFile(input);
expect(parsed.ok).toBe(false);
if (!parsed.ok) expect(parsed.error).toBe(error);
});
it("leaves out, and names, the entries this release does not know", () => {
const parsed = parseModelConfigFile({
format: MODEL_CONFIG_FILE_FORMAT,
version: MODEL_CONFIG_FILE_VERSION,
categories: { video: { model: "x/y" } },
tasks: { fallback_model: { model: "x/y" } },
});
expect(parsed.ok && parsed.ignored).toEqual(["categories.video", "tasks.fallback_model"]);
});
});