Open History to see the last commit
1import type { ServerProviderUpdateRequiredModel } from "@t3tools/contracts";
2import * as ModelCatalog from "@t3tools/provider-core/server/ModelCatalog";
3import type { ServerProviderDraft } from "@t3tools/provider-core/server/snapshotProbe";
4import { codexModelFamily } from "@t3tools/shared/model";
5import { compareSemverVersions, parseSemver } from "@t3tools/shared/semver";
6import * as Option from "effect/Option";
7import * as Schema from "effect/Schema";
8import { TrimmedNonEmptyString } from "@t3tools/contracts";
9
10const CODEX_MATCHING: ModelCatalog.CatalogMatching = { family: codexModelFamily };
11
12const CodexModelAdapter = Schema.Struct({
13 codex: Schema.optional(Schema.Struct({ minVersion: Schema.optional(TrimmedNonEmptyString) })),
14});
15const decodeCodexModelAdapter = Schema.decodeUnknownOption(CodexModelAdapter);
16
17/** Codex catalogs omit models released after the installed CLI. */
18function codexUpdateRequiredModels(
19 catalog: ModelCatalog.ProviderCatalog | undefined,
20 draft: ServerProviderDraft,
21): ReadonlyArray<ServerProviderUpdateRequiredModel> {
22 const version = draft.version?.replace(/^v/, "");
23 if (!catalog || !version || parseSemver(version) === null) return [];
24 const discovered = new Set(draft.models.map((model) => codexModelFamily(model.slug)));
25 return catalog.models.flatMap((entry) => {
26 if (entry.status !== "current" || discovered.has(codexModelFamily(entry.slug))) return [];
27 const minVersion = Option.getOrUndefined(decodeCodexModelAdapter(entry.adapter ?? {}))?.codex
28 ?.minVersion;
29 if (!minVersion || parseSemver(minVersion) === null) return [];
30 if (compareSemverVersions(version, minVersion) >= 0) return [];
31 return [
32 {
33 slug: entry.slug,
34 name: entry.name,
35 ...(entry.badge ? { badge: entry.badge } : {}),
36 minVersion,
37 },
38 ];
39 });
40}
41
42export function applyCodexModelCatalog(
43 draft: ServerProviderDraft,
44 catalog: ModelCatalog.ProviderCatalog | undefined,
45): ServerProviderDraft {
46 const updateRequiredModels = codexUpdateRequiredModels(catalog, draft);
47 return {
48 ...ModelCatalog.applyModelCatalog(draft, catalog, CODEX_MATCHING),
49 ...(updateRequiredModels.length > 0 ? { updateRequiredModels } : {}),
50 };
51}