Files
makelore/src/lib/coding-model-options.ts

59 lines
1.9 KiB
TypeScript

import type { ProviderAccount, ProviderVendorInfo } from '@/lib/providers';
import type { ProductModelRef } from '@/types/coding-conversation';
export interface CodingModelOption {
key: string;
accountId: string;
modelId: string;
label: string;
}
export function codingModelKey(model: Pick<ProductModelRef, 'accountId' | 'modelId'>): string {
return JSON.stringify([model.accountId, model.modelId]);
}
export function parseCodingModelKey(key: string): Pick<ProductModelRef, 'accountId' | 'modelId'> | null {
try {
const value = JSON.parse(key) as unknown;
if (!Array.isArray(value) || value.length !== 2) return null;
const [accountId, modelId] = value;
if (typeof accountId !== 'string' || !accountId.trim()
|| typeof modelId !== 'string' || !modelId.trim()) return null;
return { accountId: accountId.trim(), modelId: modelId.trim() };
} catch {
return null;
}
}
export function buildCodingModelOptions(
accounts: ProviderAccount[],
vendors: ProviderVendorInfo[],
): CodingModelOption[] {
const vendorNames = new Map(vendors.map((vendor) => [vendor.id, vendor.name]));
const seen = new Set<string>();
const options: CodingModelOption[] = [];
for (const account of accounts) {
if (!account.enabled) continue;
const modelIds = [
account.model,
...(account.fallbackModels ?? []),
...(account.metadata?.customModels ?? []),
];
for (const value of modelIds) {
const modelId = value?.trim();
if (!modelId) continue;
const key = codingModelKey({ accountId: account.id, modelId });
if (seen.has(key)) continue;
seen.add(key);
const vendor = vendorNames.get(account.vendorId);
options.push({
key,
accountId: account.id,
modelId,
label: `${account.label}${vendor && vendor !== account.label ? ` · ${vendor}` : ''} / ${modelId}`,
});
}
}
return options;
}