Files
KimiCodeSwitch/scripts/fetch-models-dev.mjs
T
KimiSwitch Dev 139af18826 feat: v0.3.0 - fix provider data loss, oauth corruption & switch UX
Bug fixes:
- Fix config.toml wiped to single provider on switch (now writes all providers)
- Fix managed:kimi-code oauth key corruption (oauth/kimi-code was rewritten
  to oauth/managed-kimi-code, breaking the official subscription)
- Fix default_model not switching due to React 18 deferred state update
  (updateConfig now sets configRef synchronously before setConfig)
- Strip KimiSwitch-private default_model from config.toml provider output

Architecture:
- config.toml is now the authoritative source for Kimi Code provider data
- SQLite stores only metadata (notes, official URLs, remembered models)
- Load reconciles config.toml with SQLite for external /provider changes
- Activate is a no-op for KimiCode (save already writes config.toml)

Features:
- Selected provider moves to top of list on switch
- Add models-dev context size lookup
- Add tauri-plugin-single-instance

Tests:
- 3 new regression tests: oauth key round-trip, all-providers write,
  private default_model strip
2026-07-27 22:36:42 +08:00

58 lines
2.0 KiB
JavaScript

#!/usr/bin/env node
/**
* Fetch the latest model reference data from models.dev and write a compact
* snapshot to src/lib/models-dev.json.
*
* Run manually (`npm run fetch-models-dev`) or automatically before builds
* (`prebuild`). Requires network access to models.dev.
*/
import { writeFile, mkdir } from "node:fs/promises";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
const SOURCE_URL = "https://models.dev/models.json";
const ROOT = join(dirname(fileURLToPath(import.meta.url)), "..");
const OUTPUT = join(ROOT, "src", "lib", "models-dev.json");
const res = await fetch(SOURCE_URL, {
headers: { Accept: "application/json" },
signal: AbortSignal.timeout(30_000),
});
if (!res.ok) {
throw new Error(`GET ${SOURCE_URL} returned HTTP ${res.status}`);
}
/** @type {Record<string, any>} */
const raw = await res.json();
// Keep only the fields the app needs; the raw file carries benchmarks,
// descriptions, etc. that would bloat the bundle.
const snapshot = {};
for (const [key, m] of Object.entries(raw)) {
if (!m || typeof m !== "object") continue;
const entry = {};
if (typeof m.name === "string") entry.name = m.name;
// context 0 means "not applicable" (image/audio models) — treat as missing
// so callers fall back to regex defaults instead of storing 0.
if (typeof m.limit?.context === "number" && m.limit.context > 0) {
entry.context = m.limit.context;
}
if (m.reasoning === true) entry.reasoning = true;
if (m.tool_call === true) entry.tool_call = true;
if (m.structured_output === true) entry.structured_output = true;
const input = m.modalities?.input;
if (Array.isArray(input)) {
if (input.includes("image")) entry.image = true;
if (input.includes("video")) entry.video = true;
}
snapshot[key] = entry;
}
await mkdir(dirname(OUTPUT), { recursive: true });
await writeFile(OUTPUT, JSON.stringify(snapshot, null, 2) + "\n", "utf8");
console.log(
`models-dev snapshot: ${Object.keys(snapshot).length} models -> ${OUTPUT}`,
);