180 lines · 6.1 KB · TypeScript
RawDownload
import { describe, expect, it } from "vitest";import {  CURSOR_MODEL_FAMILY_OPTIONS,  CURSOR_REASONING_OPTIONS,  DEFAULT_MODEL,  DEFAULT_MODEL_BY_PROVIDER,  DEFAULT_REASONING_EFFORT_BY_PROVIDER,  MODEL_OPTIONS,  MODEL_OPTIONS_BY_PROVIDER,  REASONING_EFFORT_OPTIONS_BY_PROVIDER,} from "../../contracts/src"; import {  getDefaultModel,  getDefaultReasoningEffort,  getCursorModelFamilyOptions,  getModelOptions,  getReasoningEffortOptions,  normalizeModelSlug,  parseCursorModelSelection,  resolveCursorModelFromSelection,  resolveModelSlug,  resolveModelSlugForProvider,} from "./model"; describe("normalizeModelSlug", () => {  it("maps known aliases to canonical slugs", () => {    expect(normalizeModelSlug("5.3")).toBe("gpt-5.3-codex");    expect(normalizeModelSlug("gpt-5.3")).toBe("gpt-5.3-codex");  });   it("returns null for empty or missing values", () => {    expect(normalizeModelSlug("")).toBeNull();    expect(normalizeModelSlug("   ")).toBeNull();    expect(normalizeModelSlug(null)).toBeNull();    expect(normalizeModelSlug(undefined)).toBeNull();  });   it("preserves non-aliased model slugs", () => {    expect(normalizeModelSlug("gpt-5.2")).toBe("gpt-5.2");    expect(normalizeModelSlug("gpt-5.2-codex")).toBe("gpt-5.2-codex");  });   it("uses provider-specific aliases", () => {    expect(normalizeModelSlug("sonnet", "claudeCode")).toBe("claude-sonnet-4-6");    expect(normalizeModelSlug("opus-4.6", "claudeCode")).toBe("claude-opus-4-6");    expect(normalizeModelSlug("claude-haiku-4-5-20251001", "claudeCode")).toBe(      "claude-haiku-4-5",    );    expect(normalizeModelSlug("composer", "cursor")).toBe("composer-1.5");    expect(normalizeModelSlug("gpt-5.3-codex-spark", "cursor")).toBe(      "gpt-5.3-codex-spark-preview",    );    expect(normalizeModelSlug("gemini-3.1", "cursor")).toBe("gemini-3.1");    expect(normalizeModelSlug("claude-4.6-sonnet-thinking", "cursor")).toBe(      "sonnet-4.6-thinking",    );  });}); describe("resolveModelSlug", () => {  it("returns default only when the model is missing", () => {    expect(resolveModelSlug(undefined)).toBe(DEFAULT_MODEL);    expect(resolveModelSlug(null)).toBe(DEFAULT_MODEL);  });   it("preserves unknown custom models", () => {    expect(resolveModelSlug("gpt-4.1")).toBe(DEFAULT_MODEL);    expect(resolveModelSlug("custom/internal-model")).toBe(DEFAULT_MODEL);  });   it("resolves only supported model options", () => {    for (const model of MODEL_OPTIONS) {      expect(resolveModelSlug(model.slug)).toBe(model.slug);    }  });   it("supports provider-aware resolution", () => {    expect(resolveModelSlugForProvider("claudeCode", undefined)).toBe(      DEFAULT_MODEL_BY_PROVIDER.claudeCode,    );    expect(resolveModelSlugForProvider("claudeCode", "sonnet")).toBe("claude-sonnet-4-6");    expect(resolveModelSlugForProvider("claudeCode", "gpt-5.3-codex")).toBe(      DEFAULT_MODEL_BY_PROVIDER.claudeCode,    );    expect(resolveModelSlugForProvider("cursor", undefined)).toBe(      DEFAULT_MODEL_BY_PROVIDER.cursor,    );    expect(resolveModelSlugForProvider("cursor", "composer")).toBe("composer-1.5");    expect(resolveModelSlugForProvider("cursor", "gpt-5.3-codex-high-fast")).toBe(      "gpt-5.3-codex-high-fast",    );    expect(resolveModelSlugForProvider("cursor", "claude-sonnet-4-6")).toBe(      DEFAULT_MODEL_BY_PROVIDER.cursor,    );  });   it("keeps codex defaults for backward compatibility", () => {    expect(getDefaultModel()).toBe(DEFAULT_MODEL);    expect(getModelOptions()).toEqual(MODEL_OPTIONS);    expect(getModelOptions("claudeCode")).toEqual(MODEL_OPTIONS_BY_PROVIDER.claudeCode);    expect(getModelOptions("cursor")).toEqual(MODEL_OPTIONS_BY_PROVIDER.cursor);    expect(getCursorModelFamilyOptions()).toEqual(CURSOR_MODEL_FAMILY_OPTIONS);  });}); describe("cursor model selection", () => {  it("includes the expected cursor reasoning levels and families", () => {    expect(CURSOR_REASONING_OPTIONS).toEqual(["low", "normal", "high", "xhigh"]);    expect(getCursorModelFamilyOptions().map((option) => option.slug)).toContain("gpt-5.3-codex");    expect(getCursorModelFamilyOptions().map((option) => option.slug)).toContain("opus-4.6");  });   it("parses codex reasoning and fast mode variants", () => {    expect(parseCursorModelSelection("gpt-5.3-codex-high-fast")).toEqual({      family: "gpt-5.3-codex",      reasoning: "high",      fast: true,      thinking: false,    });    expect(parseCursorModelSelection("gpt-5.2-codex")).toEqual(      parseCursorModelSelection(DEFAULT_MODEL_BY_PROVIDER.cursor),    );  });   it("parses and resolves thinking variants", () => {    expect(parseCursorModelSelection("sonnet-4.6-thinking")).toEqual({      family: "sonnet-4.6",      reasoning: "normal",      fast: false,      thinking: true,    });    expect(      resolveCursorModelFromSelection({        family: "sonnet-4.6",        thinking: true,      }),    ).toBe("sonnet-4.6-thinking");  });   it("resolves codex family selections into concrete model ids", () => {    expect(      resolveCursorModelFromSelection({        family: "gpt-5.3-codex",        reasoning: "xhigh",        fast: true,      }),    ).toBe("gpt-5.3-codex-xhigh-fast");  });}); describe("getReasoningEffortOptions", () => {  it("returns codex reasoning options for codex", () => {    expect(getReasoningEffortOptions("codex")).toEqual(      REASONING_EFFORT_OPTIONS_BY_PROVIDER.codex,    );  });   it("returns no reasoning options for claudeCode", () => {    expect(getReasoningEffortOptions("claudeCode")).toEqual([]);  });   it("returns no reasoning options for cursor", () => {    expect(getReasoningEffortOptions("cursor")).toEqual([]);  });}); describe("getDefaultReasoningEffort", () => {  it("returns provider-scoped defaults", () => {    expect(getDefaultReasoningEffort("codex")).toBe(      DEFAULT_REASONING_EFFORT_BY_PROVIDER.codex,    );    expect(getDefaultReasoningEffort("claudeCode")).toBe(      DEFAULT_REASONING_EFFORT_BY_PROVIDER.claudeCode,    );    expect(getDefaultReasoningEffort("cursor")).toBe(      DEFAULT_REASONING_EFFORT_BY_PROVIDER.cursor,    );  });});