|
@@ -8,30 +8,30 @@
|
|
|
* Creates the provider if it does not exist yet.
|
|
* Creates the provider if it does not exist yet.
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
-import { Plugin, Model } from "@opencode/plugin";
|
|
|
|
|
|
|
+import { Plugin, type Model } from "@opencode/plugin";
|
|
|
|
|
|
|
|
-function parseJsonc(text: string): any {
|
|
|
|
|
|
|
+function parseJsonc(text: string): unknown {
|
|
|
try { return JSON.parse(text); } catch {}
|
|
try { return JSON.parse(text); } catch {}
|
|
|
let s = text.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
let s = text.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
|
s = s.replace(/,\s*([}\]])/g, "$1");
|
|
s = s.replace(/,\s*([}\]])/g, "$1");
|
|
|
return JSON.parse(s);
|
|
return JSON.parse(s);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function readConfigProviders(): Record<string, any> {
|
|
|
|
|
- const fs = require("node:fs");
|
|
|
|
|
- const path = require("node:path");
|
|
|
|
|
- const os = require("node:os");
|
|
|
|
|
|
|
+function readConfigProviders(): Record<string, unknown> {
|
|
|
|
|
+ const fs = require("node:fs") as { existsSync: (p: string) => boolean; readFileSync: (p: string, e: string) => string };
|
|
|
|
|
+ const path = require("node:path") as { join: (...a: string[]) => string };
|
|
|
|
|
+ const os = require("node:os") as { homedir: () => string };
|
|
|
const candidates = [
|
|
const candidates = [
|
|
|
path.join(process.cwd(), "opencode.jsonc"),
|
|
path.join(process.cwd(), "opencode.jsonc"),
|
|
|
path.join(process.cwd(), "opencode.json"),
|
|
path.join(process.cwd(), "opencode.json"),
|
|
|
path.join(os.homedir(), ".config", "opencode", "opencode.jsonc"),
|
|
path.join(os.homedir(), ".config", "opencode", "opencode.jsonc"),
|
|
|
];
|
|
];
|
|
|
- const merged: Record<string, any> = {};
|
|
|
|
|
|
|
+ const merged: Record<string, unknown> = {};
|
|
|
for (const c of candidates) {
|
|
for (const c of candidates) {
|
|
|
try {
|
|
try {
|
|
|
if (!fs.existsSync(c)) continue;
|
|
if (!fs.existsSync(c)) continue;
|
|
|
- const cfg = parseJsonc(fs.readFileSync(c, "utf8"));
|
|
|
|
|
- const provs = cfg?.providers || cfg?.provider;
|
|
|
|
|
|
|
+ const cfg = parseJsonc(fs.readFileSync(c, "utf8")) as Record<string, unknown>;
|
|
|
|
|
+ const provs = (cfg?.providers || cfg?.provider) as Record<string, unknown> | undefined;
|
|
|
if (provs && typeof provs === "object") {
|
|
if (provs && typeof provs === "object") {
|
|
|
for (const [k, v] of Object.entries(provs)) {
|
|
for (const [k, v] of Object.entries(provs)) {
|
|
|
if (!merged[k]) merged[k] = v;
|
|
if (!merged[k]) merged[k] = v;
|
|
@@ -60,7 +60,7 @@ function hasOptIn(settings: Record<string, unknown>): boolean {
|
|
|
|
|
|
|
|
async function fetchModels(baseURL: string, apiKey: string): Promise<Model.Info[]> {
|
|
async function fetchModels(baseURL: string, apiKey: string): Promise<Model.Info[]> {
|
|
|
const headers: Record<string, string> = { "Content-Type": "application/json" };
|
|
const headers: Record<string, string> = { "Content-Type": "application/json" };
|
|
|
- if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
|
|
|
|
|
|
|
+ if (apiKey) headers.Authorization = `Bearer ${apiKey}`;
|
|
|
const res = await fetch(`${baseURL}/models`, { headers });
|
|
const res = await fetch(`${baseURL}/models`, { headers });
|
|
|
if (!res.ok) throw new Error(`HTTP ${res.status} from ${baseURL}/models`);
|
|
if (!res.ok) throw new Error(`HTTP ${res.status} from ${baseURL}/models`);
|
|
|
const json = await res.json();
|
|
const json = await res.json();
|