SPB Git forge

spb/polyllm

Public
15commits 1branches 0releases
2.2 MBsize
maindefault branch
13 days agolast push
TypeScript 97.4% SQL 1% JavaScript 0.9% CSS 0.6%
3.0 KB · 50 lines typescript
Raw Blame History
1import { describe, it, expect } from "vitest";2import type { PolyModel } from "@/lib/ai/core/types";3import { slugify, modelSlug, compareSlug, parseCompareSlug, findModelBySlug, resolveCompareSlug } from "@/lib/models/slug";45const caps: PolyModel["capabilities"] = { text: true, vision: false, audioInput: false, audioOutput: false, imageGeneration: false, video: false, reasoning: false, tools: false, structuredOutput: false, streaming: true, files: false, webSearch: false };6function m(provider: PolyModel["provider"], id: string, displayName: string, over: Partial<PolyModel> = {}): PolyModel {7  return { key: `${provider}/${id}`, id, provider, displayName, capabilities: caps, parameters: {}, status: "active", pricing: null, metadata: { sortWeight: 50 }, ...over };8}910const MODELS = [11  m("openai", "gpt-5.5", "GPT-5.5"),12  m("openai", "gpt-5.5-2026-04-01", "GPT-5.5 (2026-04-01)", { metadata: { sortWeight: 40 } }),13  m("anthropic", "claude-sonnet-5", "Claude Sonnet 5"),14  m("openrouter", "openai/gpt-5.5", "OpenAI: GPT-5.5"),15  m("openrouter", "meta-llama/llama-3.1-8b-instruct:free", "Meta: Llama 3.1 8B Instruct (free)"),16  m("gemini", "gemini-3.8-flash", "Gemini 3.8 Flash"),17];1819describe("slug", () => {20  it("slugifies keeping dots", () => {21    expect(slugify("GPT-5.5")).toBe("gpt-5.5");22    expect(slugify("Claude Sonnet 5")).toBe("claude-sonnet-5");23    expect(slugify("meta-llama/llama-3.1-8b-instruct:free")).toBe("meta-llama-llama-3.1-8b-instruct-free");24    expect(slugify("  --weird__ id. ")).toBe("weird-id");25  });26  it("builds and parses compare slugs", () => {27    expect(compareSlug([MODELS[0], MODELS[2]])).toBe("gpt-5.5-vs-claude-sonnet-5");28    expect(parseCompareSlug("gpt-5.5-vs-claude-sonnet-5")).toEqual(["gpt-5.5", "claude-sonnet-5"]);29    expect(parseCompareSlug("a-vs-b-vs-c-vs-d")).toHaveLength(4);30    expect(parseCompareSlug("only-one")).toBeNull();31    expect(parseCompareSlug("a-vs-b-vs-c-vs-d-vs-e")).toBeNull();32    expect(parseCompareSlug("a-vs-")).toBeNull();33    expect(parseCompareSlug("a-vs-b c")).toBeNull();34  });35  it("resolves parts by id or display name, preferring native providers", () => {36    expect(findModelBySlug(MODELS, "gpt-5.5")?.key).toBe("openai/gpt-5.5");37    expect(findModelBySlug(MODELS, "claude-sonnet-5")?.key).toBe("anthropic/claude-sonnet-5");38    expect(findModelBySlug(MODELS, "gemini-3.8-flash")?.key).toBe("gemini/gemini-3.8-flash");39    expect(findModelBySlug(MODELS, "openai-gpt-5.5")?.key).toBe("openai/gpt-5.5");40    expect(findModelBySlug(MODELS, "meta-llama-llama-3.1-8b-instruct-free")?.provider).toBe("openrouter");41    expect(findModelBySlug(MODELS, "nope")).toBeUndefined();42  });43  it("resolves full compare slugs and rejects duplicates / unknowns", () => {44    expect(resolveCompareSlug(MODELS, "gpt-5.5-vs-claude-sonnet-5")?.map((x) => x.key)).toEqual(["openai/gpt-5.5", "anthropic/claude-sonnet-5"]);45    expect(resolveCompareSlug(MODELS, "gpt-5.5-vs-gpt-5.5")).toBeNull();46    expect(resolveCompareSlug(MODELS, "gpt-5.5-vs-unknown-model")).toBeNull();47    expect(modelSlug(MODELS[3])).toBe("openai-gpt-5.5");48  });49});50