Files
next-tjwater-agent/.opencode/model-check.ts
T
jiang d58bd19039 feat(agent): unify models and validate OpenCode providers
Generate chat, task and learning models from agent-models.json.
Use WaterNetwork fast/expert models with 272k context and validate
upstream names before readiness. Add an isolated model check command
with signal-safe cleanup and plugin, Skill and MCP management docs.

Verified in isolation: type checks, 26 focused tests and both model
catalog checks; no model inference requests.
2026-10-09 11:28:37 +08:00

60 lines
3.9 KiB
TypeScript

import type { Plugin } from "@opencode/plugin";
import { modelCheckInputSchema, type ModelCheckInput, type ModelCheckReport } from "../src/runtime/model-check.js";
type Context = Parameters<Plugin.Plugin["setup"]>[0];
const catalogPackage = /^(?:@opencode\/ai\/providers\/(?:openai(?:\/chat|\/responses)?|openai-compatible(?:\/responses)?|openrouter|xai))$/;
// Runs inside OpenCode and uses its effective provider and model definitions.
// A manually registered model ID is only valid after upstream advertisement.
export async function checkOpencodeModels(ctx: Pick<Context, "model" | "provider">, input: ModelCheckInput, signal: AbortSignal): Promise<ModelCheckReport> {
const targets = modelCheckInputSchema.parse(input).models;
const nativeModels = (await ctx.model.list({}, { signal })).data;
const report: ModelCheckReport = {
providers: [],
models: targets.map((target) => {
const model = nativeModels.find((model) => model.providerID === target.provider_id && model.id === target.model_id);
return { id: target.id, model_id: target.wire_id, status: !model ? "not_registered" : !model.enabled ? "not_enabled"
: target.requires_tools && !model.capabilities.tools ? "no_tools" : model.modelID !== target.wire_id ? "wire_id_mismatch" : "unchecked" };
}),
};
await Promise.all([...new Set(targets.map((target) => target.provider_id))].map(async (providerID) => {
const providerReport: ModelCheckReport["providers"][number] = { id: providerID, status: "not_registered" };
report.providers.push(providerReport);
let provider;
try { provider = (await ctx.provider.get({ providerID }, { signal })).data; }
catch { return; }
if (!catalogPackage.test(provider.package)) { providerReport.status = "unsupported_catalog"; return; }
const baseURL = provider.settings?.baseURL;
if (typeof baseURL !== "string") { providerReport.status = "catalog_unavailable"; return; }
let endpoint: URL;
try {
endpoint = new URL(`${baseURL.replace(/\/+$/, "")}/models`);
if (!["http:", "https:"].includes(endpoint.protocol) || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) throw new Error();
} catch { providerReport.status = "catalog_unavailable"; return; }
let headers: Headers;
try {
headers = new Headers(provider.headers);
headers.set("Accept", "application/json");
const apiKey = provider.settings?.apiKey;
if (!headers.has("Authorization") && typeof apiKey === "string" && apiKey.trim()) headers.set("Authorization", `Bearer ${apiKey}`);
// An explicit header can also carry a service-owned credential.
if (!headers.has("Authorization")) throw new Error();
} catch { providerReport.status = "credentials_unavailable"; return; }
try {
const response = await fetch(endpoint, { headers, redirect: "error", signal: AbortSignal.any([signal, AbortSignal.timeout(10_000)]) });
if (!response.ok) { providerReport.status = "catalog_unavailable"; providerReport.http_status = response.status; return; }
const payload: unknown = await response.json();
const data = payload && typeof payload === "object" && "data" in payload ? payload.data : undefined;
if (!Array.isArray(data) || data.some((model) => !model || typeof model.id !== "string")) { providerReport.status = "catalog_invalid"; return; }
const advertised = new Set(data.map((model) => model.id as string));
providerReport.status = "checked";
for (const target of targets.filter((target) => target.provider_id === providerID)) {
const model = report.models.find((model) => model.id === target.id)!;
if (model.status === "unchecked") model.status = advertised.has(target.wire_id) ? "valid" : "not_advertised";
}
} catch { providerReport.status = "catalog_unavailable"; }
}));
report.providers.sort((a, b) => a.id.localeCompare(b.id));
return report;
}