summaryrefslogtreecommitdiffhomepage
path: root/src/features/chat/model-select.test.ts
blob: 6d3081db4fd3262f491c5dbe9204cd8610192f1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { describe, expect, it } from "vitest";
import {
  isVisionModel,
  joinModelName,
  modelKeys,
  modelsForKey,
  splitModelName,
} from "./model-select";

describe("splitModelName", () => {
  it("splits on the first slash", () => {
    expect(splitModelName("openai/gpt-4")).toEqual({ key: "openai", model: "gpt-4" });
  });

  it("keeps slashes in the model part (splits only the first)", () => {
    expect(splitModelName("openrouter/anthropic/claude")).toEqual({
      key: "openrouter",
      model: "anthropic/claude",
    });
  });

  it("treats a slashless name as all key", () => {
    expect(splitModelName("local")).toEqual({ key: "local", model: "" });
  });
});

describe("joinModelName", () => {
  it("recombines key + model", () => {
    expect(joinModelName("openai", "gpt-4")).toBe("openai/gpt-4");
  });

  it("returns just the key when the model is empty", () => {
    expect(joinModelName("local", "")).toBe("local");
  });

  it("round-trips with splitModelName", () => {
    const full = "openrouter/anthropic/claude";
    const { key, model } = splitModelName(full);
    expect(joinModelName(key, model)).toBe(full);
  });
});

describe("modelKeys", () => {
  it("returns distinct keys in first-seen order", () => {
    expect(
      modelKeys(["openai/gpt-4", "openai/gpt-4o", "anthropic/claude-3", "google/gemini"]),
    ).toEqual(["openai", "anthropic", "google"]);
  });

  it("is empty for no models", () => {
    expect(modelKeys([])).toEqual([]);
  });
});

describe("modelsForKey", () => {
  it("returns the model suffixes under a key, in order", () => {
    const models = ["openai/gpt-4", "anthropic/claude-3", "openai/gpt-4o"];
    expect(modelsForKey(models, "openai")).toEqual(["gpt-4", "gpt-4o"]);
  });

  it("returns empty for an unknown key", () => {
    expect(modelsForKey(["openai/gpt-4"], "anthropic")).toEqual([]);
  });
});

describe("isVisionModel", () => {
  it("returns true when modelInfo[name].vision is true", () => {
    const info = { "kimi/k2": { vision: true } };
    expect(isVisionModel(info, "kimi/k2")).toBe(true);
  });

  it("returns false when vision is false", () => {
    const info = { "umans/glm-5.2": { vision: false } };
    expect(isVisionModel(info, "umans/glm-5.2")).toBe(false);
  });

  it("returns false when vision is absent (unknown)", () => {
    const info = { "umans/glm-5.2": { contextWindow: 128000 } };
    expect(isVisionModel(info, "umans/glm-5.2")).toBe(false);
  });

  it("returns false for a model with no metadata entry at all", () => {
    expect(isVisionModel({}, "unknown/model")).toBe(false);
  });

  it("returns false for an empty modelInfo map", () => {
    expect(isVisionModel({}, "kimi/k2")).toBe(false);
  });
});