import { describe, expect, it } from "vitest";import { DEFAULT_MODEL, DEFAULT_MODEL_BY_PROVIDER, type ModelCapabilities,} from "@t3tools/contracts"; import { applyClaudePromptEffortPrefix, getDefaultEffort, hasEffortLevel, isClaudeUltrathinkPrompt, normalizeModelSlug, resolveModelSlug, resolveModelSlugForProvider, resolveSelectableModel, trimOrNull,} from "./model"; const codexCaps: ModelCapabilities = { reasoningEffortLevels: [ { value: "xhigh", label: "Extra High" }, { value: "high", label: "High", isDefault: true }, ], supportsFastMode: true, supportsThinkingToggle: false, promptInjectedEffortLevels: [],}; const claudeCaps: ModelCapabilities = { reasoningEffortLevels: [ { value: "medium", label: "Medium" }, { value: "high", label: "High", isDefault: true }, { value: "ultrathink", label: "Ultrathink" }, ], supportsFastMode: false, supportsThinkingToggle: false, promptInjectedEffortLevels: ["ultrathink"],}; describe("normalizeModelSlug", () => { it("maps known aliases to canonical slugs", () => { expect(normalizeModelSlug("5.3")).toBe("gpt-5.3-codex"); expect(normalizeModelSlug("sonnet", "claudeAgent")).toBe("claude-sonnet-4-6"); }); it("returns null for empty or missing values", () => { expect(normalizeModelSlug("")).toBeNull(); expect(normalizeModelSlug(" ")).toBeNull(); expect(normalizeModelSlug(null)).toBeNull(); expect(normalizeModelSlug(undefined)).toBeNull(); });}); describe("resolveModelSlug", () => { it("returns defaults when the model is missing", () => { expect(resolveModelSlug(undefined)).toBe(DEFAULT_MODEL); expect(resolveModelSlugForProvider("claudeAgent", undefined)).toBe( DEFAULT_MODEL_BY_PROVIDER.claudeAgent, ); }); it("preserves normalized unknown models", () => { expect(resolveModelSlug("custom/internal-model")).toBe("custom/internal-model"); });}); describe("resolveSelectableModel", () => { it("resolves exact slugs, labels, and aliases", () => { const options = [ { slug: "gpt-5.3-codex", name: "GPT-5.3 Codex" }, { slug: "claude-sonnet-4-6", name: "Claude Sonnet 4.6" }, ]; expect(resolveSelectableModel("codex", "gpt-5.3-codex", options)).toBe("gpt-5.3-codex"); expect(resolveSelectableModel("codex", "gpt-5.3 codex", options)).toBe("gpt-5.3-codex"); expect(resolveSelectableModel("claudeAgent", "sonnet", options)).toBe("claude-sonnet-4-6"); });}); describe("capability helpers", () => { it("reads default efforts", () => { expect(getDefaultEffort(codexCaps)).toBe("high"); expect(getDefaultEffort(claudeCaps)).toBe("high"); }); it("checks effort support", () => { expect(hasEffortLevel(codexCaps, "xhigh")).toBe(true); expect(hasEffortLevel(codexCaps, "max")).toBe(false); });}); describe("misc helpers", () => { it("detects ultrathink prompts", () => { expect(isClaudeUltrathinkPrompt("Ultrathink:\nInvestigate")).toBe(true); expect(isClaudeUltrathinkPrompt("Investigate")).toBe(false); }); it("prefixes ultrathink prompts once", () => { expect(applyClaudePromptEffortPrefix("Investigate", "ultrathink")).toBe( "Ultrathink:\nInvestigate", ); expect(applyClaudePromptEffortPrefix("Ultrathink:\nInvestigate", "ultrathink")).toBe( "Ultrathink:\nInvestigate", ); }); it("trims strings to null", () => { expect(trimOrNull(" hi ")).toBe("hi"); expect(trimOrNull(" ")).toBeNull(); });});
import { describe, expect, it } from "vitest";
import {
DEFAULT_MODEL,
DEFAULT_MODEL_BY_PROVIDER,
type ModelCapabilities,
} from "@t3tools/contracts";
import {
applyClaudePromptEffortPrefix,
getDefaultEffort,
hasEffortLevel,
isClaudeUltrathinkPrompt,
normalizeModelSlug,
resolveModelSlug,
resolveModelSlugForProvider,
resolveSelectableModel,
trimOrNull,
} from "./model";
const codexCaps: ModelCapabilities = {
reasoningEffortLevels: [
{ value: "xhigh", label: "Extra High" },
{ value: "high", label: "High", isDefault: true },
],
supportsFastMode: true,
supportsThinkingToggle: false,
promptInjectedEffortLevels: [],
};
const claudeCaps: ModelCapabilities = {
reasoningEffortLevels: [
{ value: "medium", label: "Medium" },
{ value: "high", label: "High", isDefault: true },
{ value: "ultrathink", label: "Ultrathink" },
],
supportsFastMode: false,
supportsThinkingToggle: false,
promptInjectedEffortLevels: ["ultrathink"],
};
describe("normalizeModelSlug", () => {
it("maps known aliases to canonical slugs", () => {
expect(normalizeModelSlug("5.3")).toBe("gpt-5.3-codex");
expect(normalizeModelSlug("sonnet", "claudeAgent")).toBe("claude-sonnet-4-6");
});
it("returns null for empty or missing values", () => {
expect(normalizeModelSlug("")).toBeNull();
expect(normalizeModelSlug(" ")).toBeNull();
expect(normalizeModelSlug(null)).toBeNull();
expect(normalizeModelSlug(undefined)).toBeNull();
});
});
describe("resolveModelSlug", () => {
it("returns defaults when the model is missing", () => {
expect(resolveModelSlug(undefined)).toBe(DEFAULT_MODEL);
expect(resolveModelSlugForProvider("claudeAgent", undefined)).toBe(
DEFAULT_MODEL_BY_PROVIDER.claudeAgent,
);
});
it("preserves normalized unknown models", () => {
expect(resolveModelSlug("custom/internal-model")).toBe("custom/internal-model");
});
});
describe("resolveSelectableModel", () => {
it("resolves exact slugs, labels, and aliases", () => {
const options = [
{ slug: "gpt-5.3-codex", name: "GPT-5.3 Codex" },
{ slug: "claude-sonnet-4-6", name: "Claude Sonnet 4.6" },
];
expect(resolveSelectableModel("codex", "gpt-5.3-codex", options)).toBe("gpt-5.3-codex");
expect(resolveSelectableModel("codex", "gpt-5.3 codex", options)).toBe("gpt-5.3-codex");
expect(resolveSelectableModel("claudeAgent", "sonnet", options)).toBe("claude-sonnet-4-6");
});
});
describe("capability helpers", () => {
it("reads default efforts", () => {
expect(getDefaultEffort(codexCaps)).toBe("high");
expect(getDefaultEffort(claudeCaps)).toBe("high");
});
it("checks effort support", () => {
expect(hasEffortLevel(codexCaps, "xhigh")).toBe(true);
expect(hasEffortLevel(codexCaps, "max")).toBe(false);
});
});
describe("misc helpers", () => {
it("detects ultrathink prompts", () => {
expect(isClaudeUltrathinkPrompt("Ultrathink:\nInvestigate")).toBe(true);
expect(isClaudeUltrathinkPrompt("Investigate")).toBe(false);
});
it("prefixes ultrathink prompts once", () => {
expect(applyClaudePromptEffortPrefix("Investigate", "ultrathink")).toBe(
"Ultrathink:\nInvestigate",
);
expect(applyClaudePromptEffortPrefix("Ultrathink:\nInvestigate", "ultrathink")).toBe(
"Ultrathink:\nInvestigate",
);
});
it("trims strings to null", () => {
expect(trimOrNull(" hi ")).toBe("hi");
expect(trimOrNull(" ")).toBeNull();
});
});