Spaces:
Runtime error
Runtime error
| import { NextResponse } from "next/server"; | |
| import { getModelAliases, setModelAlias, deleteModelAlias, isCloudEnabled } from "@/models"; | |
| import { getConsistentMachineId } from "@/shared/utils/machineId"; | |
| import { syncToCloud } from "@/lib/cloudSync"; | |
| import { cloudModelAliasUpdateSchema } from "@/shared/validation/schemas"; | |
| import { isValidationFailure, validateBody } from "@/shared/validation/helpers"; | |
| import { | |
| INTERNAL_PROXY_ERROR, | |
| getCatalogDiagnosticsHeaders, | |
| resolveModelAliasLookup, | |
| } from "@/lib/modelMetadataRegistry"; | |
| import { requireManagementAuth } from "@/lib/api/requireManagementAuth"; | |
| // GET /api/models/alias - Get all aliases | |
| export async function GET(request) { | |
| const alias = new URL(request.url).searchParams.get("alias"); | |
| try { | |
| const authError = await requireManagementAuth(request); | |
| if (authError) { | |
| const headers = getCatalogDiagnosticsHeaders({ request, resolvedAlias: alias }); | |
| for (const [key, value] of Object.entries(headers)) { | |
| authError.headers.set(key, value); | |
| } | |
| return authError; | |
| } | |
| if (alias) { | |
| const resolved = await resolveModelAliasLookup(alias); | |
| if (!resolved.ok) { | |
| return NextResponse.json( | |
| { | |
| error: { | |
| message: resolved.error.message, | |
| code: resolved.error.code, | |
| ...(resolved.error.candidates ? { candidates: resolved.error.candidates } : {}), | |
| }, | |
| }, | |
| { | |
| status: resolved.error.status, | |
| headers: getCatalogDiagnosticsHeaders({ request, resolvedAlias: alias }), | |
| } | |
| ); | |
| } | |
| return NextResponse.json( | |
| { | |
| alias: resolved.value.alias, | |
| resolved: { | |
| provider: resolved.value.provider, | |
| providerAlias: resolved.value.providerAlias, | |
| model: resolved.value.model, | |
| qualifiedId: resolved.value.resolvedAlias, | |
| source: resolved.value.source, | |
| target: resolved.value.target, | |
| metadata: resolved.value.metadata, | |
| }, | |
| catalogVersion: getCatalogDiagnosticsHeaders({ request })["X-Model-Catalog-Version"], | |
| }, | |
| { | |
| headers: getCatalogDiagnosticsHeaders({ | |
| request, | |
| resolvedAlias: resolved.value.resolvedAlias, | |
| }), | |
| } | |
| ); | |
| } | |
| const aliases = await getModelAliases(); | |
| return NextResponse.json( | |
| { | |
| aliases, | |
| catalogVersion: getCatalogDiagnosticsHeaders({ request })["X-Model-Catalog-Version"], | |
| }, | |
| { | |
| headers: getCatalogDiagnosticsHeaders({ request }), | |
| } | |
| ); | |
| } catch (error) { | |
| console.log("Error fetching aliases:", error); | |
| return NextResponse.json( | |
| { | |
| error: { | |
| message: "Failed to fetch aliases", | |
| code: INTERNAL_PROXY_ERROR, | |
| }, | |
| }, | |
| { | |
| status: 500, | |
| headers: getCatalogDiagnosticsHeaders({ request, resolvedAlias: alias }), | |
| } | |
| ); | |
| } | |
| } | |
| // PUT /api/models/alias - Set model alias | |
| export async function PUT(request) { | |
| const diagnosticHeaders = getCatalogDiagnosticsHeaders({ request }); | |
| let rawBody; | |
| try { | |
| rawBody = await request.json(); | |
| } catch { | |
| return NextResponse.json( | |
| { | |
| error: { | |
| message: "Invalid request", | |
| details: [{ field: "body", message: "Invalid JSON body" }], | |
| }, | |
| }, | |
| { status: 400, headers: diagnosticHeaders } | |
| ); | |
| } | |
| try { | |
| const authError = await requireManagementAuth(request); | |
| if (authError) { | |
| for (const [key, value] of Object.entries(diagnosticHeaders)) { | |
| authError.headers.set(key, value); | |
| } | |
| return authError; | |
| } | |
| const validation = validateBody(cloudModelAliasUpdateSchema, rawBody); | |
| if (isValidationFailure(validation)) { | |
| return NextResponse.json( | |
| { error: validation.error }, | |
| { status: 400, headers: diagnosticHeaders } | |
| ); | |
| } | |
| const { model, alias } = validation.data; | |
| await setModelAlias(alias, model); | |
| await syncToCloudIfEnabled(); | |
| return NextResponse.json( | |
| { success: true, model, alias }, | |
| { | |
| headers: getCatalogDiagnosticsHeaders({ request, resolvedAlias: alias }), | |
| } | |
| ); | |
| } catch (error) { | |
| console.log("Error updating alias:", error); | |
| return NextResponse.json( | |
| { | |
| error: { | |
| message: "Failed to update alias", | |
| code: INTERNAL_PROXY_ERROR, | |
| }, | |
| }, | |
| { status: 500, headers: diagnosticHeaders } | |
| ); | |
| } | |
| } | |
| // DELETE /api/models/alias?alias=xxx - Delete alias | |
| export async function DELETE(request) { | |
| const diagnosticHeaders = getCatalogDiagnosticsHeaders({ request }); | |
| try { | |
| const authError = await requireManagementAuth(request); | |
| if (authError) { | |
| for (const [key, value] of Object.entries(diagnosticHeaders)) { | |
| authError.headers.set(key, value); | |
| } | |
| return authError; | |
| } | |
| const { searchParams } = new URL(request.url); | |
| const alias = searchParams.get("alias"); | |
| if (!alias) { | |
| return NextResponse.json( | |
| { error: "Alias required" }, | |
| { status: 400, headers: diagnosticHeaders } | |
| ); | |
| } | |
| await deleteModelAlias(alias); | |
| await syncToCloudIfEnabled(); | |
| return NextResponse.json( | |
| { success: true }, | |
| { | |
| headers: getCatalogDiagnosticsHeaders({ request, resolvedAlias: alias }), | |
| } | |
| ); | |
| } catch (error) { | |
| console.log("Error deleting alias:", error); | |
| return NextResponse.json( | |
| { | |
| error: { | |
| message: "Failed to delete alias", | |
| code: INTERNAL_PROXY_ERROR, | |
| }, | |
| }, | |
| { status: 500, headers: diagnosticHeaders } | |
| ); | |
| } | |
| } | |
| async function syncToCloudIfEnabled() { | |
| try { | |
| const cloudEnabled = await isCloudEnabled(); | |
| if (!cloudEnabled) return; | |
| const machineId = await getConsistentMachineId(); | |
| await syncToCloud(machineId); | |
| } catch (error) { | |
| console.log("Error syncing aliases to cloud:", error); | |
| } | |
| } | |