Skip to main content
Glama
route.ts5.66 kB
/** * Copyright (C) 2023 the project owner * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ import { NextResponse } from "next/server" import { readFile, writeFile } from "fs/promises" import { join } from "path" // Path to settings.json (always in project root) const PROJECT_ROOT = join(process.cwd(), "..") const SETTINGS_FILE = join(PROJECT_ROOT, "settings.json") interface ModelSettings { quick: string coder: string moe: string thinking: string } interface OllamaModel { name: string size: number modified_at: string } interface BackendConfig { id: string name: string provider: string type: string url: string enabled: boolean priority: number models: ModelSettings } interface SettingsConfig { backends: BackendConfig[] routing: { prefer_local: boolean } } async function loadSettings(): Promise<SettingsConfig> { try { const content = await readFile(SETTINGS_FILE, "utf-8") return JSON.parse(content) } catch { return { backends: [], routing: { prefer_local: true } } } } async function saveSettings(config: SettingsConfig): Promise<void> { await writeFile(SETTINGS_FILE, JSON.stringify(config, null, 2), "utf-8") } // Get active backend from settings function getActiveBackend(config: SettingsConfig): BackendConfig | undefined { const enabled = config.backends.filter(b => b.enabled) if (enabled.length === 0) return undefined // Sort by priority (assuming 0 is highest, or just take first) // Matching python logic: priority sort enabled.sort((a, b) => (a.priority || 0) - (b.priority || 0)) return enabled[0] } // Fetch available models from backend async function fetchModels(backend: BackendConfig): Promise<OllamaModel[]> { if (backend.provider !== "ollama") return [] try { const res = await fetch(`${backend.url}/api/tags`, { signal: AbortSignal.timeout(5000) }) if (res.ok) { const data = await res.json() return data.models || [] } } catch { // Backend not available } return [] } export async function GET() { try { const config = await loadSettings() const activeBackend = getActiveBackend(config) if (!activeBackend) { return NextResponse.json({ success: false, error: "No active backend found", models: { quick: "", coder: "", moe: "", thinking: "" }, availableModels: [], ollamaConnected: false }) } const models = activeBackend.models // Fetch available models from the active backend const backendModels = await fetchModels(activeBackend) const availableModels = backendModels.map(m => ({ name: m.name, size: m.size, sizeGB: (m.size / 1024 / 1024 / 1024).toFixed(1) })) return NextResponse.json({ success: true, models, availableModels, ollamaConnected: backendModels.length > 0 }) } catch (error) { return NextResponse.json({ success: false, error: (error as Error).message, }, { status: 500 }) } } export async function POST(request: Request) { try { const body = await request.json() const { tier, model } = body as { tier: "quick" | "coder" | "moe" | "thinking", model: string } if (!tier || !model) { return NextResponse.json({ success: false, error: "Missing tier or model parameter", }, { status: 400 }) } if (!["quick", "coder", "moe", "thinking"].includes(tier)) { return NextResponse.json({ success: false, error: "Invalid tier. Must be quick, coder, moe, or thinking", }, { status: 400 }) } // Read current config const config = await loadSettings() // Find active backend to update // Note: We update the specific backend object in the array const enabled = config.backends.filter(b => b.enabled) if (enabled.length === 0) { return NextResponse.json({ success: false, error: "No active backend to update", }, { status: 404 }) } // Sort to find the active one enabled.sort((a, b) => (a.priority || 0) - (b.priority || 0)) const activeId = enabled[0].id const backendIndex = config.backends.findIndex(b => b.id === activeId) if (backendIndex === -1) { return NextResponse.json({ success: false, error: "Active backend not found in list", }, { status: 404 }) } // Update the model if (!config.backends[backendIndex].models) { config.backends[backendIndex].models = { quick: "", coder: "", moe: "", thinking: "" } } config.backends[backendIndex].models[tier] = model // Write back await saveSettings(config) return NextResponse.json({ success: true, message: `Updated ${tier} model to ${model} for backend ${config.backends[backendIndex].name}`, }) } catch (error) { return NextResponse.json({ success: false, error: (error as Error).message, }, { status: 500 }) } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/zbrdc/delia'

If you have feedback or need assistance with the MCP directory API, please join our Discord server