1import { assert, describe, it } from "@effect/vitest";
2import type { ServerProviderModel } from "@t3tools/contracts";
3
4import * as ModelCatalog from "./ModelCatalog.ts";
5
6const model = (overrides: Partial<ServerProviderModel>): ServerProviderModel => ({
7 slug: "model-test",
8 name: "Model Test",
9 isCustom: false,
10 capabilities: null,
11 ...overrides,
12});
13
14const catalogModel = (
15 slug: string,
16 status: ModelCatalog.ProviderCatalogModel["status"],
17): ModelCatalog.ProviderCatalogModel => ({
18 slug,
19 name: slug,
20 status,
21 capabilities: null,
22 adapter: undefined,
23 profileAdapter: undefined,
24});
25
26const prefixFamily: ModelCatalog.CatalogMatching = {
27 family: (slug) => slug.replace(/^vendor\./, ""),
28};
29
30describe("classifyCatalogModels", () => {
31 it("flags only known legacy models, clears stale flags, and skips custom models", () => {
32 const catalog: ModelCatalog.ProviderCatalog = {
33 models: [catalogModel("old-model", "legacy")],
34 defaultChatModel: undefined,
35 };
36 const models = [
37 model({ slug: "current-a" }),
38 model({ slug: "current-b", isLegacy: true }),
39 model({ slug: "old-model" }),
40 model({ slug: "my-own-model", isCustom: true, isLegacy: true }),
41 ];
42 assert.deepStrictEqual(
43 ModelCatalog.classifyCatalogModels(models, catalog).map((entry) => [
44 entry.slug,
45 entry.isLegacy ?? false,
46 ]),
47 [
48 ["current-a", false],
49 ["current-b", false],
50 ["old-model", true],
51 ["my-own-model", true],
52 ],
53 );
54 });
55
56 it("matches qualified slugs through the driver's family without changing their ids", () => {
57 const catalog: ModelCatalog.ProviderCatalog = {
58 models: [catalogModel("model-old", "legacy")],
59 defaultChatModel: undefined,
60 };
61 assert.deepStrictEqual(
62 ModelCatalog.classifyCatalogModels(
63 [model({ slug: "vendor.model-test", isLegacy: true }), model({ slug: "vendor.model-old" })],
64 catalog,
65 prefixFamily,
66 ).map((entry) => [entry.slug, entry.isLegacy ?? false]),
67 [
68 ["vendor.model-test", false],
69 ["vendor.model-old", true],
70 ],
71 );
72 });
73});
74
75describe("applyCatalogDefault", () => {
76 it("moves the default flag and its aliases to the catalog's chat default", () => {
77 const catalog: ModelCatalog.ProviderCatalog = {
78 models: [catalogModel("model-new", "current")],
79 defaultChatModel: "model-new",
80 };
81 const models = [
82 model({ slug: "model-old", isDefault: true, aliases: ["provider-default"] }),
83 model({ slug: "model-new" }),
84 ];
85 assert.deepStrictEqual(ModelCatalog.applyCatalogDefault(models, catalog), [
86 model({ slug: "model-old" }),
87 model({ slug: "model-new", isDefault: true, aliases: ["provider-default"] }),
88 ]);
89 assert.deepStrictEqual(
90 ModelCatalog.applyCatalogDefault(models.slice(0, 1), catalog),
91 models.slice(0, 1),
92 );
93 });
94
95 it("resolves the catalog default to a qualified discovered model", () => {
96 const catalog: ModelCatalog.ProviderCatalog = {
97 models: [],
98 defaultChatModel: "model-test",
99 };
100 const models = [
101 model({ slug: "vendor.model-old", isDefault: true }),
102 model({ slug: "vendor.model-test" }),
103 ];
104 assert.strictEqual(
105 ModelCatalog.applyCatalogDefault(models, catalog, prefixFamily).find(
106 (entry) => entry.isDefault,
107 )?.slug,
108 "vendor.model-test",
109 );
110 });
111});