Skip to content

Commit dabdc77

Browse files
committed
feat: add manifest model catalog planner
1 parent 7920f8d commit dabdc77

2 files changed

Lines changed: 101 additions & 0 deletions

File tree

src/model-catalog/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ export {
88
normalizeModelCatalogProviderRows,
99
normalizeModelCatalogRows,
1010
} from "./normalize.js";
11+
export { planManifestModelCatalogRows } from "./manifest-planner.js";
12+
export type {
13+
ManifestModelCatalogPlan,
14+
ManifestModelCatalogPlanEntry,
15+
ManifestModelCatalogPlugin,
16+
ManifestModelCatalogRegistry,
17+
} from "./manifest-planner.js";
1118
export type {
1219
ModelCatalog,
1320
ModelCatalogAlias,
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { normalizeModelCatalogProviderRows } from "./normalize.js";
2+
import { normalizeModelCatalogProviderId } from "./refs.js";
3+
import type { ModelCatalog, NormalizedModelCatalogRow } from "./types.js";
4+
5+
export type ManifestModelCatalogPlugin = {
6+
id: string;
7+
modelCatalog?: Pick<ModelCatalog, "providers">;
8+
};
9+
10+
export type ManifestModelCatalogRegistry = {
11+
plugins: readonly ManifestModelCatalogPlugin[];
12+
};
13+
14+
export type ManifestModelCatalogPlanEntry = {
15+
pluginId: string;
16+
provider: string;
17+
rows: readonly NormalizedModelCatalogRow[];
18+
};
19+
20+
export type ManifestModelCatalogPlan = {
21+
rows: readonly NormalizedModelCatalogRow[];
22+
entries: readonly ManifestModelCatalogPlanEntry[];
23+
};
24+
25+
export function planManifestModelCatalogRows(params: {
26+
registry: ManifestModelCatalogRegistry;
27+
providerFilter?: string;
28+
}): ManifestModelCatalogPlan {
29+
const providerFilter = params.providerFilter
30+
? normalizeModelCatalogProviderId(params.providerFilter)
31+
: undefined;
32+
const entries: ManifestModelCatalogPlanEntry[] = [];
33+
34+
for (const plugin of params.registry.plugins) {
35+
for (const entry of planManifestModelCatalogPluginEntries({ plugin, providerFilter })) {
36+
entries.push(entry);
37+
}
38+
}
39+
40+
const rows: NormalizedModelCatalogRow[] = [];
41+
const seenMergeKeys = new Set<string>();
42+
for (const entry of entries) {
43+
for (const row of entry.rows) {
44+
if (seenMergeKeys.has(row.mergeKey)) {
45+
continue;
46+
}
47+
seenMergeKeys.add(row.mergeKey);
48+
rows.push(row);
49+
}
50+
}
51+
52+
return {
53+
entries,
54+
rows: rows.toSorted(
55+
(left, right) =>
56+
left.provider.localeCompare(right.provider) || left.id.localeCompare(right.id),
57+
),
58+
};
59+
}
60+
61+
function planManifestModelCatalogPluginEntries(params: {
62+
plugin: ManifestModelCatalogPlugin;
63+
providerFilter: string | undefined;
64+
}): ManifestModelCatalogPlanEntry[] {
65+
const providers = params.plugin.modelCatalog?.providers;
66+
if (!providers) {
67+
return [];
68+
}
69+
70+
return Object.entries(providers).flatMap(([provider, providerCatalog]) => {
71+
const normalizedProvider = normalizeModelCatalogProviderId(provider);
72+
if (
73+
!normalizedProvider ||
74+
(params.providerFilter && normalizedProvider !== params.providerFilter)
75+
) {
76+
return [];
77+
}
78+
const rows = normalizeModelCatalogProviderRows({
79+
provider: normalizedProvider,
80+
providerCatalog,
81+
source: "manifest",
82+
});
83+
if (rows.length === 0) {
84+
return [];
85+
}
86+
return [
87+
{
88+
pluginId: params.plugin.id,
89+
provider: normalizedProvider,
90+
rows,
91+
},
92+
];
93+
});
94+
}

0 commit comments

Comments
 (0)