import type { Doc } from './_generated/dataModel'; import { query } from './_generated/server'; import { getRequiredUserId } from './model'; type AiProviderProfileWithDefault = Doc<'aiProviderProfiles'> & { isDefault?: boolean; }; const labelForModel = (model: string): string => { const parts = model.split('/'); const raw = parts[parts.length - 1] ?? model; return raw .replaceAll('-', ' ') .replace(/\b\w/g, (letter: string) => letter.toUpperCase()); }; const recommendedFor = (model: string) => { const lower = model.toLowerCase(); const tags: ('coding' | 'review' | 'fast' | 'large_context')[] = []; if ( lower.includes('codex') || lower.includes('claude') || lower.includes('sonnet') ) { tags.push('coding'); } if ( lower.includes('mini') || lower.includes('haiku') || lower.includes('flash') ) { tags.push('fast'); } if ( lower.includes('200k') || lower.includes('1m') || lower.includes('large') ) { tags.push('large_context'); } if (!tags.length) tags.push('review'); return tags; }; export const listAvailableForUser = query({ args: {}, handler: async (ctx) => { const ownerId = await getRequiredUserId(ctx); const profiles = await ctx.db .query('aiProviderProfiles') .withIndex('by_owner', (q) => q.eq('ownerId', ownerId)) .order('desc') .collect(); const configuredProfiles = profiles.filter( (profile) => profile.enabled && (profile.authType === 'none' || Boolean(profile.encryptedSecret)), ); const explicitDefault = configuredProfiles.find( (profile) => (profile as AiProviderProfileWithDefault).isDefault, ); const defaultProfileId = explicitDefault?._id ?? (configuredProfiles.length === 1 ? configuredProfiles[0]?._id : undefined); return { profiles: profiles .filter((profile) => profile.enabled) .map((profile) => { const configured = profile.authType === 'none' || Boolean(profile.encryptedSecret); const modelIds = [ profile.defaultModel, ...(profile.modelOptions ?? []), ] .map((model) => model.trim()) .filter(Boolean) .filter((model, index, all) => all.indexOf(model) === index); return { profileId: profile._id, profileName: profile.name, provider: profile.provider, configured, enabled: profile.enabled, isDefault: profile._id === defaultProfileId, defaultModel: profile.defaultModel, reasoningEffort: profile.reasoningEffort, models: modelIds.map((id) => ({ id, label: labelForModel(id), recommendedFor: recommendedFor(id), })), }; }), }; }, });