import { createLogger } from '@sim/logger' import { toError } from '@sim/utils/errors' import { type NextRequest, NextResponse } from 'next/server' import { copilotModelsContract } from '@/lib/api/contracts/copilot' import { parseRequest } from '@/lib/api/server' import { fetchGo } from '@/lib/copilot/request/go/fetch' import { authenticateCopilotRequestSessionOnly } from '@/lib/copilot/request/http' import { getMothershipBaseURL } from '@/lib/copilot/server/agent-url' import { env } from '@/lib/core/config/env' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' interface AvailableModel { id: string friendlyName: string provider: string } const logger = createLogger('CopilotModelsAPI') interface RawAvailableModel { id: string friendlyName?: string displayName?: string provider?: string } function isRawAvailableModel(item: unknown): item is RawAvailableModel { return ( typeof item === 'object' && item !== null && 'id' in item && typeof (item as { id: unknown }).id === 'string' ) } export const GET = withRouteHandler(async (req: NextRequest) => { const parsed = await parseRequest(copilotModelsContract, req, {}) if (!parsed.success) return parsed.response const { userId, isAuthenticated } = await authenticateCopilotRequestSessionOnly() if (!isAuthenticated || !userId) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } const headers: Record = { 'Content-Type': 'application/json', } if (env.COPILOT_API_KEY) { headers['x-api-key'] = env.COPILOT_API_KEY } try { const mothershipBaseURL = await getMothershipBaseURL({ userId }) const response = await fetchGo(`${mothershipBaseURL}/api/get-available-models`, { method: 'GET', headers, cache: 'no-store', spanName: 'sim → go /api/get-available-models', operation: 'get_available_models', }) const payload = await response.json().catch(() => ({})) if (!response.ok) { logger.warn('Failed to fetch available models from copilot backend', { status: response.status, }) return NextResponse.json( { success: false, error: payload?.error || 'Failed to fetch available models', models: [], }, { status: response.status } ) } const rawModels = Array.isArray(payload?.models) ? payload.models : [] const models: AvailableModel[] = rawModels .filter((item: unknown): item is RawAvailableModel => isRawAvailableModel(item)) .map((item: RawAvailableModel) => ({ id: item.id, friendlyName: item.friendlyName || item.displayName || item.id, provider: item.provider || 'unknown', })) return NextResponse.json({ success: true, models }) } catch (error) { logger.error('Error fetching available models', { error: toError(error).message, }) return NextResponse.json( { success: false, error: 'Failed to fetch available models', models: [], }, { status: 500 } ) } })