feat(cli-tools): add OpenCode tool integration to CLI Tools page
This commit is contained in:
parent
03fc685f72
commit
38ded5c62f
6 changed files with 457 additions and 36 deletions
148
src/app/api/cli-tools/copilot-settings/route.js
Normal file
148
src/app/api/cli-tools/copilot-settings/route.js
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
"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");
|
||||
return JSON.parse(content);
|
||||
} catch (error) {
|
||||
if (error.code === "ENOENT") return null;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
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 });
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue