Spaces:
Sleeping
Sleeping
| "use server"; | |
| import { NextResponse } from "next/server"; | |
| import fs from "fs/promises"; | |
| import path from "path"; | |
| import os from "os"; | |
| // Resolve chatLanguageModels.json path per OS | |
| const getConfigPath = () => { | |
| const home = os.homedir(); | |
| const platform = os.platform(); | |
| if (platform === "win32") { | |
| return path.join(process.env.APPDATA || home, "Code", "User", "chatLanguageModels.json"); | |
| } | |
| if (platform === "darwin") { | |
| return path.join(home, "Library", "Application Support", "Code", "User", "chatLanguageModels.json"); | |
| } | |
| return path.join(home, ".config", "Code", "User", "chatLanguageModels.json"); | |
| }; | |
| const readConfig = async () => { | |
| try { | |
| const content = await fs.readFile(getConfigPath(), "utf-8"); | |
| // Tolerate JSONC (trailing commas) and treat unparseable files as "no config" | |
| // rather than throwing a 500 that the UI misreads as "tool not installed". | |
| const stripped = content.replace(/,(\s*[}\]])/g, "$1"); | |
| return JSON.parse(stripped); | |
| } catch (error) { | |
| return null; | |
| } | |
| }; | |
| const has9RouterConfig = (config) => { | |
| if (!Array.isArray(config)) return false; | |
| return config.some((entry) => entry.name === "9Router"); | |
| }; | |
| const get9RouterEntry = (config) => { | |
| if (!Array.isArray(config)) return null; | |
| return config.find((entry) => entry.name === "9Router") || null; | |
| }; | |
| // GET - Read current copilot config | |
| export async function GET() { | |
| try { | |
| const config = await readConfig(); | |
| const entry = get9RouterEntry(config); | |
| return NextResponse.json({ | |
| installed: true, | |
| config, | |
| has9Router: has9RouterConfig(config), | |
| configPath: getConfigPath(), | |
| currentModel: entry?.models?.[0]?.id || null, | |
| currentUrl: entry?.models?.[0]?.url || null, | |
| }); | |
| } catch (error) { | |
| console.log("Error checking copilot settings:", error); | |
| return NextResponse.json({ error: "Failed to check copilot settings" }, { status: 500 }); | |
| } | |
| } | |
| // POST - Apply 9Router config to chatLanguageModels.json | |
| export async function POST(request) { | |
| try { | |
| const { baseUrl, apiKey, models } = await request.json(); | |
| if (!baseUrl || !models?.length) { | |
| return NextResponse.json({ error: "baseUrl and models are required" }, { status: 400 }); | |
| } | |
| const configPath = getConfigPath(); | |
| await fs.mkdir(path.dirname(configPath), { recursive: true }); | |
| // Read existing config array | |
| let config = []; | |
| try { | |
| const existing = await fs.readFile(configPath, "utf-8"); | |
| const parsed = JSON.parse(existing); | |
| config = Array.isArray(parsed) ? parsed : []; | |
| } catch { /* No existing config */ } | |
| const endpointUrl = `${baseUrl}/chat/completions#models.ai.azure.com`; | |
| const keyToUse = apiKey || "sk_9router"; | |
| const newEntry = { | |
| name: "9Router", | |
| vendor: "azure", | |
| apiKey: keyToUse, | |
| models: models.map((id) => ({ | |
| id, | |
| name: id, | |
| url: endpointUrl, | |
| toolCalling: true, | |
| vision: false, | |
| maxInputTokens: 128000, | |
| maxOutputTokens: 16000, | |
| })), | |
| }; | |
| // Replace existing 9Router entry or append | |
| const idx = config.findIndex((e) => e.name === "9Router"); | |
| if (idx >= 0) { | |
| config[idx] = newEntry; | |
| } else { | |
| config.push(newEntry); | |
| } | |
| await fs.writeFile(configPath, JSON.stringify(config, null, 2)); | |
| return NextResponse.json({ | |
| success: true, | |
| message: "Copilot settings applied! Reload VS Code to take effect.", | |
| configPath, | |
| }); | |
| } catch (error) { | |
| console.log("Error updating copilot settings:", error); | |
| return NextResponse.json({ error: "Failed to update copilot settings" }, { status: 500 }); | |
| } | |
| } | |
| // DELETE - Remove 9Router entry from chatLanguageModels.json | |
| export async function DELETE() { | |
| try { | |
| const configPath = getConfigPath(); | |
| let config = []; | |
| try { | |
| const existing = await fs.readFile(configPath, "utf-8"); | |
| const parsed = JSON.parse(existing); | |
| config = Array.isArray(parsed) ? parsed : []; | |
| } catch (error) { | |
| if (error.code === "ENOENT") { | |
| return NextResponse.json({ success: true, message: "No config file to reset" }); | |
| } | |
| throw error; | |
| } | |
| config = config.filter((e) => e.name !== "9Router"); | |
| await fs.writeFile(configPath, JSON.stringify(config, null, 2)); | |
| return NextResponse.json({ | |
| success: true, | |
| message: "9Router removed from Copilot config", | |
| }); | |
| } catch (error) { | |
| console.log("Error resetting copilot settings:", error); | |
| return NextResponse.json({ error: "Failed to reset copilot settings" }, { status: 500 }); | |
| } | |
| } | |