saros-proxy 1.0.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -16
- package/assets/models.json +3349 -0
- package/dist/cli/autostart.d.ts +13 -6
- package/dist/cli/autostart.js +317 -60
- package/dist/cli/autostart.js.map +1 -1
- package/dist/cli/daemon.js +89 -14
- package/dist/cli/daemon.js.map +1 -1
- package/dist/cli/harness-models.d.ts +5 -4
- package/dist/cli/harness-models.js +77 -30
- package/dist/cli/harness-models.js.map +1 -1
- package/dist/cli/help.js +5 -0
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/log-render.d.ts +16 -0
- package/dist/cli/log-render.js +82 -0
- package/dist/cli/log-render.js.map +1 -0
- package/dist/cli/opencode-config.d.ts +1 -0
- package/dist/cli/opencode-config.js +7 -6
- package/dist/cli/opencode-config.js.map +1 -1
- package/dist/config.js +20 -4
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +2 -0
- package/dist/constants.js.map +1 -1
- package/dist/index.js +29 -36
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +16 -0
- package/dist/logger.js +56 -23
- package/dist/logger.js.map +1 -1
- package/dist/model-ladder.d.ts +30 -0
- package/dist/model-ladder.js +45 -0
- package/dist/model-ladder.js.map +1 -0
- package/dist/models-catalog.d.ts +25 -4
- package/dist/models-catalog.js +41 -12
- package/dist/models-catalog.js.map +1 -1
- package/dist/models-dev.d.ts +72 -0
- package/dist/models-dev.js +196 -0
- package/dist/models-dev.js.map +1 -0
- package/dist/models-refresh.d.ts +144 -0
- package/dist/models-refresh.js +522 -0
- package/dist/models-refresh.js.map +1 -0
- package/dist/models-sync.d.ts +6 -10
- package/dist/models-sync.js +26 -60
- package/dist/models-sync.js.map +1 -1
- package/package.json +5 -5
- package/models.json +0 -1440
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* models-refresh.ts — Deterministic generator for the bundled model catalog.
|
|
3
|
+
*
|
|
4
|
+
* `npm run models:refresh` (scripts/refresh-models.ts) is the only writer of
|
|
5
|
+
* `assets/models.json`. It merges models.dev metadata for the two providers
|
|
6
|
+
* this proxy serves with the live catalogs, so a model that no longer exists
|
|
7
|
+
* upstream leaves the bundle and a new one enters without a hand edit.
|
|
8
|
+
*
|
|
9
|
+
* The merge is a pure function (`mergeModelCatalog`) so the catalog rules are
|
|
10
|
+
* testable without network access:
|
|
11
|
+
* - membership follows the live catalogs: a model the provider serves enters
|
|
12
|
+
* with the metadata the live payload carries even when models.dev omits it,
|
|
13
|
+
* and it stays while the provider keeps advertising it;
|
|
14
|
+
* - `opencode-go` metadata wins when both providers know a model;
|
|
15
|
+
* - a field already in the current file survives when models.dev is silent
|
|
16
|
+
* about it (models.dev drops fields occasionally and a regeneration must
|
|
17
|
+
* not discard the value);
|
|
18
|
+
* - two raw ids that collapse to the same bare key abort the refresh;
|
|
19
|
+
* - output keys, including nested object keys, are sorted so a refresh diff
|
|
20
|
+
* only shows real changes;
|
|
21
|
+
* - a failed fetch — or an empty/partial response — aborts before the file is
|
|
22
|
+
* read, and a merge that would drop more than half of the current models
|
|
23
|
+
* needs `allowShrink` before it writes anything.
|
|
24
|
+
*/
|
|
25
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
26
|
+
import { DEFAULT_UPSTREAM_COMMANDCODE, DEFAULT_UPSTREAM_URL, MODELS_DEV_COMMANDCODE_PROVIDER_ID, MODELS_DEV_SAFE_FIELDS, MODELS_DEV_TIMEOUT_MS, MODELS_DEV_URL, MODELS_DEV_PROVIDER_ID, MODELS_FETCH_TIMEOUT_MS, } from './constants.js';
|
|
27
|
+
import { OPENCODE_GO_USER_AGENT } from './providers/opencode-go.js';
|
|
28
|
+
import { conservativeEffortOptions } from './model-ladder.js';
|
|
29
|
+
import { parseCatalogObject, serializeCatalogObject } from './models-catalog.js';
|
|
30
|
+
import { extractProviderModels } from './models-dev.js';
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// Sources
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
/** Public opencode-go catalog — no auth, but Cloudflare wants a CLI signature. */
|
|
35
|
+
export const OPENCODE_GO_MODELS_URL = `${DEFAULT_UPSTREAM_URL}/zen/go/v1/models`;
|
|
36
|
+
/** Public CommandCode catalog (200 with any or no Authorization header). */
|
|
37
|
+
export const COMMANDCODE_MODELS_URL = `${DEFAULT_UPSTREAM_COMMANDCODE}/provider/v1/models`;
|
|
38
|
+
/**
|
|
39
|
+
* models.dev sits behind Cloudflare and answers 403 `error code: 1010` to
|
|
40
|
+
* browser-like or missing signatures. Any stable non-browser UA works.
|
|
41
|
+
*/
|
|
42
|
+
export const MODELS_REFRESH_USER_AGENT = 'saros-proxy-models-refresh';
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// Fetching
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
/** GET a JSON document with one User-Agent header. Throws on any non-2xx. */
|
|
47
|
+
async function fetchJson(url, userAgent, label, fetchImpl, timeoutMs) {
|
|
48
|
+
const response = await fetchImpl(url, {
|
|
49
|
+
headers: { 'User-Agent': userAgent },
|
|
50
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
51
|
+
});
|
|
52
|
+
if (!response.ok)
|
|
53
|
+
throw new Error(`${label} returned HTTP ${response.status}`);
|
|
54
|
+
return response.json();
|
|
55
|
+
}
|
|
56
|
+
/** Fetch and validate the models.dev catalog. */
|
|
57
|
+
export async function fetchModelsDevCatalog(fetchImpl = fetch, timeoutMs = MODELS_DEV_TIMEOUT_MS) {
|
|
58
|
+
const parsed = await fetchJson(MODELS_DEV_URL, MODELS_REFRESH_USER_AGENT, 'models.dev', fetchImpl, timeoutMs);
|
|
59
|
+
if (!isPlainObject(parsed))
|
|
60
|
+
throw new Error('models.dev returned a non-object payload');
|
|
61
|
+
return parsed;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Fetch the opencode-go live catalog.
|
|
65
|
+
*
|
|
66
|
+
* The list is authoritative for membership: models.dev keeps models the
|
|
67
|
+
* provider already retired (`space-bunny`, `cat-jam-free`, …), and publishing
|
|
68
|
+
* those as connectable models is what this gate prevents.
|
|
69
|
+
*/
|
|
70
|
+
export async function fetchOpencodeGoModels(fetchImpl = fetch, timeoutMs = MODELS_FETCH_TIMEOUT_MS) {
|
|
71
|
+
return fetchLiveModels(OPENCODE_GO_MODELS_URL, OPENCODE_GO_USER_AGENT, 'opencode-go models', fetchImpl, timeoutMs, () => true);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Fetch the CommandCode live catalog.
|
|
75
|
+
*
|
|
76
|
+
* Only models that advertise `/chat/completions` are usable through the proxy,
|
|
77
|
+
* which relays chat/completions shapes. `claude-*` entries list `/messages`
|
|
78
|
+
* only (verified live: chat/completions → unsupported_model); a vendor-prefixed
|
|
79
|
+
* Claude model would slip past a bare `^claude` test, so the endpoint field —
|
|
80
|
+
* not the id — decides.
|
|
81
|
+
*/
|
|
82
|
+
export async function fetchCommandcodeModels(fetchImpl = fetch, timeoutMs = MODELS_FETCH_TIMEOUT_MS) {
|
|
83
|
+
return fetchLiveModels(COMMANDCODE_MODELS_URL, MODELS_REFRESH_USER_AGENT, 'commandcode models', fetchImpl, timeoutMs, supportsChatCompletions);
|
|
84
|
+
}
|
|
85
|
+
/** True when the live entry advertises the OpenAI chat/completions endpoint. */
|
|
86
|
+
function supportsChatCompletions(entry) {
|
|
87
|
+
const endpoints = entry.supported_endpoints;
|
|
88
|
+
return Array.isArray(endpoints) && endpoints.includes('/chat/completions');
|
|
89
|
+
}
|
|
90
|
+
/** Shared `{ object: 'list', data: [{ id }] }` parser. */
|
|
91
|
+
async function fetchLiveModels(url, userAgent, label, fetchImpl, timeoutMs, keep) {
|
|
92
|
+
const body = await fetchJson(url, userAgent, label, fetchImpl, timeoutMs);
|
|
93
|
+
if (!isPlainObject(body) || !Array.isArray(body.data)) {
|
|
94
|
+
throw new Error(`${label} returned an unexpected payload`);
|
|
95
|
+
}
|
|
96
|
+
const models = [];
|
|
97
|
+
for (const entry of body.data) {
|
|
98
|
+
if (!isPlainObject(entry) || typeof entry.id !== 'string' || entry.id.length === 0)
|
|
99
|
+
continue;
|
|
100
|
+
if (keep(entry))
|
|
101
|
+
models.push(toLiveModel(entry, entry.id));
|
|
102
|
+
}
|
|
103
|
+
return models;
|
|
104
|
+
}
|
|
105
|
+
/** Keep the fields the live payload can seed a catalog entry with. */
|
|
106
|
+
function toLiveModel(entry, id) {
|
|
107
|
+
const model = { id };
|
|
108
|
+
if (typeof entry.name === 'string' && entry.name.length > 0)
|
|
109
|
+
model.name = entry.name;
|
|
110
|
+
if (typeof entry.context_length === 'number' && Number.isFinite(entry.context_length)) {
|
|
111
|
+
model.context_length = entry.context_length;
|
|
112
|
+
}
|
|
113
|
+
return model;
|
|
114
|
+
}
|
|
115
|
+
/** Build the real fetchers — the only place the CLI touches the network. */
|
|
116
|
+
export function defaultRefreshFetchers() {
|
|
117
|
+
return {
|
|
118
|
+
modelsDev: () => fetchModelsDevCatalog(),
|
|
119
|
+
opencodeModels: () => fetchOpencodeGoModels(),
|
|
120
|
+
commandcodeModels: () => fetchCommandcodeModels(),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
// models.dev extraction
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
/**
|
|
127
|
+
* Return one provider's `models` map from a parsed models.dev payload.
|
|
128
|
+
*
|
|
129
|
+
* Thin delegate: the parse lives in `models-dev.ts` so the generator and the
|
|
130
|
+
* runtime read agree on what a provider slice is.
|
|
131
|
+
*/
|
|
132
|
+
export function extractModelsDevProviderModels(parsed, providerId) {
|
|
133
|
+
return extractProviderModels(parsed, providerId);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Merge models.dev metadata with the live catalogs and the current file.
|
|
137
|
+
*
|
|
138
|
+
* Membership is decided by upstream: only ids that the live catalog advertises
|
|
139
|
+
* are kept, and a live id enters even when models.dev has never heard of it.
|
|
140
|
+
* Fields inside a surviving entry are additive — the current file's value
|
|
141
|
+
* survives whenever the upstream source does not carry that field.
|
|
142
|
+
*/
|
|
143
|
+
export function mergeModelCatalog(input) {
|
|
144
|
+
const metadata = collectCandidates(input);
|
|
145
|
+
const live = indexLiveModels(input);
|
|
146
|
+
const current = isPlainObject(input.current) ? input.current : {};
|
|
147
|
+
const models = {};
|
|
148
|
+
const added = [];
|
|
149
|
+
const changed = [];
|
|
150
|
+
const entries = [...live].sort(([left], [right]) => (left < right ? -1 : 1));
|
|
151
|
+
for (const [key, liveModel] of entries) {
|
|
152
|
+
const base = isPlainObject(current[key]) ? current[key] : {};
|
|
153
|
+
const fromModelsDev = metadata.get(key);
|
|
154
|
+
// models.dev wins over the current file (it is the richer source); the
|
|
155
|
+
// live payload only fills the holes models.dev leaves, so a value the user
|
|
156
|
+
// customized is never replaced by a bare live stub.
|
|
157
|
+
const entry = fromModelsDev ? overlay(base, { ...fromModelsDev, id: key }) : base;
|
|
158
|
+
const merged = fillMissing(entry, liveStub(key, liveModel));
|
|
159
|
+
models[key] = sortKeysDeep({ ...merged, id: key });
|
|
160
|
+
if (!(key in current))
|
|
161
|
+
added.push(key);
|
|
162
|
+
else if (!isDeepStrictEqual(current[key], models[key]))
|
|
163
|
+
changed.push(key);
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
models,
|
|
167
|
+
added,
|
|
168
|
+
removed: Object.keys(current)
|
|
169
|
+
.filter((key) => !live.has(key))
|
|
170
|
+
.sort(),
|
|
171
|
+
changed,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/** Build the models.dev candidate map: opencode-go first, commandcode fills the gaps. */
|
|
175
|
+
function collectCandidates(input) {
|
|
176
|
+
const opencodeCatalog = extractModelsDevProviderModels(input.modelsDev, MODELS_DEV_PROVIDER_ID);
|
|
177
|
+
const commandcodeCatalog = extractModelsDevProviderModels(input.modelsDev, MODELS_DEV_COMMANDCODE_PROVIDER_ID);
|
|
178
|
+
const opencodeKeys = indexProviderIds(MODELS_DEV_PROVIDER_ID, input.opencodeModels);
|
|
179
|
+
const commandcodeKeys = indexProviderIds(MODELS_DEV_COMMANDCODE_PROVIDER_ID, input.commandcodeModels);
|
|
180
|
+
const candidates = new Map();
|
|
181
|
+
addProviderModels(candidates, MODELS_DEV_PROVIDER_ID, opencodeCatalog, opencodeKeys, false);
|
|
182
|
+
addProviderModels(candidates, MODELS_DEV_COMMANDCODE_PROVIDER_ID, commandcodeCatalog, commandcodeKeys, true);
|
|
183
|
+
return candidates;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Index both live catalogs by key. opencode-go is the primary provider, so its
|
|
187
|
+
* entry wins when the same model is served by both.
|
|
188
|
+
*/
|
|
189
|
+
function indexLiveModels(input) {
|
|
190
|
+
const byKey = new Map();
|
|
191
|
+
for (const model of [...input.opencodeModels, ...input.commandcodeModels]) {
|
|
192
|
+
const key = normalizeModelKey(model.id);
|
|
193
|
+
if (key && !byKey.has(key))
|
|
194
|
+
byKey.set(key, model);
|
|
195
|
+
}
|
|
196
|
+
return byKey;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Index one provider's live ids by catalog key, rejecting ambiguity.
|
|
200
|
+
*
|
|
201
|
+
* Two different raw ids (`vendorA/foo`, `vendorB/foo`) that collapse to the
|
|
202
|
+
* same bare key would silently overwrite each other, so the refresh aborts
|
|
203
|
+
* instead of picking one.
|
|
204
|
+
*/
|
|
205
|
+
function indexProviderIds(providerId, live) {
|
|
206
|
+
const byKey = new Map();
|
|
207
|
+
for (const model of live) {
|
|
208
|
+
const key = normalizeModelKey(model.id);
|
|
209
|
+
if (!key)
|
|
210
|
+
continue;
|
|
211
|
+
const existing = byKey.get(key);
|
|
212
|
+
if (existing)
|
|
213
|
+
throw collisionError(providerId, existing.id, model.id, key);
|
|
214
|
+
byKey.set(key, model);
|
|
215
|
+
}
|
|
216
|
+
return byKey;
|
|
217
|
+
}
|
|
218
|
+
/** The bare-name collision message: which raw ids fought over one key. */
|
|
219
|
+
function collisionError(providerId, first, second, key) {
|
|
220
|
+
return new Error(`bare-name collision in ${providerId}: "${first}" and "${second}" both map to "${key}"; `
|
|
221
|
+
+ 'rename one of them upstream or teach normalizeModelKey about the difference');
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Add one provider's models.dev entries that exist in its live catalog.
|
|
225
|
+
*
|
|
226
|
+
* @param fillOnly — keep the existing entry's fields and only fill the holes
|
|
227
|
+
* (CommandCode is secondary metadata; opencode-go is primary)
|
|
228
|
+
*/
|
|
229
|
+
function addProviderModels(target, providerId, models, allowed, fillOnly) {
|
|
230
|
+
for (const [modelId, raw] of Object.entries(models)) {
|
|
231
|
+
const key = normalizeModelKey(modelId);
|
|
232
|
+
const liveModel = allowed.get(key);
|
|
233
|
+
if (!liveModel)
|
|
234
|
+
continue;
|
|
235
|
+
// The same model under a different raw id in models.dev and the live
|
|
236
|
+
// payload is the cross-source form of the bare-name collision.
|
|
237
|
+
if (liveModel.id !== modelId)
|
|
238
|
+
throw collisionError(providerId, liveModel.id, modelId, key);
|
|
239
|
+
const entry = sanitizeEntry(raw);
|
|
240
|
+
if (!entry)
|
|
241
|
+
continue;
|
|
242
|
+
const existing = target.get(key);
|
|
243
|
+
if (!existing) {
|
|
244
|
+
target.set(key, entry);
|
|
245
|
+
}
|
|
246
|
+
else if (fillOnly) {
|
|
247
|
+
target.set(key, fillMissing(existing, entry));
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Fallback context window for a live-only model whose payload carries no
|
|
253
|
+
* `context_length`; same default `providerCatalogToCanonical` uses.
|
|
254
|
+
*/
|
|
255
|
+
const LIVE_STUB_CONTEXT_FALLBACK = 262_144;
|
|
256
|
+
/** Fallback max output tokens; same default `providerCatalogToCanonical` uses. */
|
|
257
|
+
const LIVE_STUB_OUTPUT_FALLBACK = 65_536;
|
|
258
|
+
/**
|
|
259
|
+
* Minimal catalog entry from a live payload: id, name, context window and the
|
|
260
|
+
* canonical defaults the harness pipeline (`providerCatalogToCanonical`) gives
|
|
261
|
+
* a model with no models.dev metadata. Every value here only fills a hole, so
|
|
262
|
+
* models.dev and the current file still win wherever they have a field.
|
|
263
|
+
*/
|
|
264
|
+
function liveStub(key, model) {
|
|
265
|
+
const stub = {
|
|
266
|
+
id: key,
|
|
267
|
+
tool_call: true,
|
|
268
|
+
reasoning: true,
|
|
269
|
+
limit: {
|
|
270
|
+
context: model.context_length ?? LIVE_STUB_CONTEXT_FALLBACK,
|
|
271
|
+
output: LIVE_STUB_OUTPUT_FALLBACK,
|
|
272
|
+
},
|
|
273
|
+
modalities: { input: ['text'], output: ['text'] },
|
|
274
|
+
// Conservative effort ladder: the commandcode gateway accepts
|
|
275
|
+
// low|medium|high|xhigh and rejects minimal, so declare the safe three.
|
|
276
|
+
reasoning_options: conservativeEffortOptions(),
|
|
277
|
+
};
|
|
278
|
+
if (model.name !== undefined)
|
|
279
|
+
stub.name = model.name;
|
|
280
|
+
return stub;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Normalize an id to catalog key form: bare name, lower-cased, `_` → `-`.
|
|
284
|
+
* Vendor-prefixed names (`zai-org/GLM-5.3`) collapse to their model name.
|
|
285
|
+
*/
|
|
286
|
+
function normalizeModelKey(modelId) {
|
|
287
|
+
const bare = modelId.substring(modelId.lastIndexOf('/') + 1);
|
|
288
|
+
return bare.toLowerCase().replaceAll('_', '-');
|
|
289
|
+
}
|
|
290
|
+
/** Keep only the fields the catalog schema documents. */
|
|
291
|
+
function sanitizeEntry(raw) {
|
|
292
|
+
if (!isPlainObject(raw))
|
|
293
|
+
return null;
|
|
294
|
+
const entry = {};
|
|
295
|
+
for (const field of MODELS_DEV_SAFE_FIELDS) {
|
|
296
|
+
if (field in raw)
|
|
297
|
+
entry[field] = raw[field];
|
|
298
|
+
}
|
|
299
|
+
return Object.keys(entry).length > 0 ? entry : null;
|
|
300
|
+
}
|
|
301
|
+
/** Recursive overlay: `upstream` wins at every leaf. */
|
|
302
|
+
function overlay(base, upstream) {
|
|
303
|
+
const merged = { ...base };
|
|
304
|
+
for (const [field, value] of Object.entries(upstream)) {
|
|
305
|
+
const current = merged[field];
|
|
306
|
+
merged[field] = isPlainObject(current) && isPlainObject(value)
|
|
307
|
+
? overlay(current, value)
|
|
308
|
+
: value;
|
|
309
|
+
}
|
|
310
|
+
return merged;
|
|
311
|
+
}
|
|
312
|
+
/** Recursive fill: values already in `base` survive, holes come from `extra`. */
|
|
313
|
+
function fillMissing(base, extra) {
|
|
314
|
+
const merged = { ...base };
|
|
315
|
+
for (const [field, value] of Object.entries(extra)) {
|
|
316
|
+
const current = merged[field];
|
|
317
|
+
if (!(field in merged)) {
|
|
318
|
+
merged[field] = value;
|
|
319
|
+
}
|
|
320
|
+
else if (isPlainObject(current) && isPlainObject(value)) {
|
|
321
|
+
merged[field] = fillMissing(current, value);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return merged;
|
|
325
|
+
}
|
|
326
|
+
/** Sort object keys recursively; arrays keep their order. */
|
|
327
|
+
function sortKeysDeep(value) {
|
|
328
|
+
if (Array.isArray(value))
|
|
329
|
+
return value.map(sortKeysDeep);
|
|
330
|
+
if (!isPlainObject(value))
|
|
331
|
+
return value;
|
|
332
|
+
const sorted = {};
|
|
333
|
+
for (const key of Object.keys(value).sort()) {
|
|
334
|
+
sorted[key] = sortKeysDeep(value[key]);
|
|
335
|
+
}
|
|
336
|
+
return sorted;
|
|
337
|
+
}
|
|
338
|
+
/** Plain object (not null, not an array). */
|
|
339
|
+
function isPlainObject(value) {
|
|
340
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
341
|
+
}
|
|
342
|
+
// ---------------------------------------------------------------------------
|
|
343
|
+
// Serialization & orchestration
|
|
344
|
+
// ---------------------------------------------------------------------------
|
|
345
|
+
/** Stable on-disk format: 2-space indent, sorted keys, trailing newline. */
|
|
346
|
+
export function serializeModelCatalog(models) {
|
|
347
|
+
return serializeCatalogObject(sortKeysDeep(models));
|
|
348
|
+
}
|
|
349
|
+
/** Parse a catalog file. `null`/empty content is an empty catalog. */
|
|
350
|
+
export function parseCatalogContent(raw) {
|
|
351
|
+
if (raw === null || raw.trim() === '')
|
|
352
|
+
return {};
|
|
353
|
+
return parseCatalogObject(raw);
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Fetch, merge, and (unless dry-running) write the catalog.
|
|
357
|
+
*
|
|
358
|
+
* Sources are validated before the file is read: a 2xx with an empty body (a
|
|
359
|
+
* Cloudflare hiccup, a partial rollout) used to empty the catalog and mark
|
|
360
|
+
* every model removed. A merge that would drop more than half of the current
|
|
361
|
+
* models is treated the same way unless `allowShrink` opts in.
|
|
362
|
+
*/
|
|
363
|
+
export async function refreshModelCatalog(io, fetchers = defaultRefreshFetchers(), options = {}) {
|
|
364
|
+
const [modelsDev, opencodeModels, commandcodeModels] = await Promise.all([
|
|
365
|
+
fetchers.modelsDev(),
|
|
366
|
+
fetchers.opencodeModels(),
|
|
367
|
+
fetchers.commandcodeModels(),
|
|
368
|
+
]);
|
|
369
|
+
assertRefreshSources(modelsDev, opencodeModels, commandcodeModels);
|
|
370
|
+
const previousContent = io.read();
|
|
371
|
+
const current = parseCatalogContent(previousContent);
|
|
372
|
+
const merge = mergeModelCatalog({
|
|
373
|
+
modelsDev,
|
|
374
|
+
opencodeModels,
|
|
375
|
+
commandcodeModels,
|
|
376
|
+
current,
|
|
377
|
+
});
|
|
378
|
+
assertShrinkAllowed(merge, current, options.allowShrink);
|
|
379
|
+
const nextContent = serializeModelCatalog(merge.models);
|
|
380
|
+
const bytesChanged = nextContent !== previousContent;
|
|
381
|
+
const formattingOnly = bytesChanged
|
|
382
|
+
&& merge.added.length === 0
|
|
383
|
+
&& merge.removed.length === 0
|
|
384
|
+
&& merge.changed.length === 0;
|
|
385
|
+
const written = options.dryRun !== true && bytesChanged;
|
|
386
|
+
if (written)
|
|
387
|
+
io.write(nextContent);
|
|
388
|
+
return { ...merge, previousContent, nextContent, written, formattingOnly };
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Reject a source that answered 2xx with an empty or partial payload.
|
|
392
|
+
*
|
|
393
|
+
* models.dev must carry both provider maps; each live catalog must carry at
|
|
394
|
+
* least one usable id. Anything else is a network hiccup, not a catalog.
|
|
395
|
+
*/
|
|
396
|
+
function assertRefreshSources(modelsDev, opencodeModels, commandcodeModels) {
|
|
397
|
+
for (const providerId of [MODELS_DEV_PROVIDER_ID, MODELS_DEV_COMMANDCODE_PROVIDER_ID]) {
|
|
398
|
+
const models = extractModelsDevProviderModels(modelsDev, providerId);
|
|
399
|
+
if (Object.keys(models).length === 0) {
|
|
400
|
+
throw new Error(`models.dev returned no ${providerId} models; refusing to treat an empty response as a catalog`);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (opencodeModels.length === 0) {
|
|
404
|
+
throw new Error('opencode-go returned no models; refusing to treat an empty response as a catalog');
|
|
405
|
+
}
|
|
406
|
+
if (commandcodeModels.length === 0) {
|
|
407
|
+
throw new Error('commandcode returned no models; refusing to treat an empty response as a catalog');
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Refuse a merge that removes more than half of the current models.
|
|
412
|
+
*
|
|
413
|
+
* A partial upstream response looks exactly like a mass retirement, and the
|
|
414
|
+
* resulting file would drop models the proxy still serves. `allowShrink` is
|
|
415
|
+
* the operator's statement that the removal is intentional.
|
|
416
|
+
*/
|
|
417
|
+
function assertShrinkAllowed(merge, current, allowShrink) {
|
|
418
|
+
if (allowShrink)
|
|
419
|
+
return;
|
|
420
|
+
const total = Object.keys(current).length;
|
|
421
|
+
if (total === 0 || merge.removed.length * 2 <= total)
|
|
422
|
+
return;
|
|
423
|
+
const percent = Math.round((merge.removed.length / total) * 100);
|
|
424
|
+
throw new Error(`refusing to remove ${merge.removed.length} of ${total} models (${percent}%): `
|
|
425
|
+
+ 'neither live catalog lists them any more, which is how a partial upstream response looks. '
|
|
426
|
+
+ 'Rerun with --allow-shrink if the removal is intentional');
|
|
427
|
+
}
|
|
428
|
+
// ---------------------------------------------------------------------------
|
|
429
|
+
// Diff rendering (--dry-run)
|
|
430
|
+
// ---------------------------------------------------------------------------
|
|
431
|
+
/** Human-readable model-level diff between the old and the new catalog. */
|
|
432
|
+
export function formatCatalogDiff(previous, next) {
|
|
433
|
+
const lines = [];
|
|
434
|
+
const previousModels = previous ?? {};
|
|
435
|
+
const nextKeys = Object.keys(next);
|
|
436
|
+
for (const key of Object.keys(previousModels).sort()) {
|
|
437
|
+
if (!(key in next))
|
|
438
|
+
lines.push(...entryBlock('-', key, previousModels[key]));
|
|
439
|
+
}
|
|
440
|
+
for (const key of nextKeys) {
|
|
441
|
+
if (!(key in previousModels))
|
|
442
|
+
lines.push(...entryBlock('+', key, next[key]));
|
|
443
|
+
}
|
|
444
|
+
for (const key of nextKeys) {
|
|
445
|
+
if (!(key in previousModels))
|
|
446
|
+
continue;
|
|
447
|
+
if (isDeepStrictEqual(previousModels[key], next[key]))
|
|
448
|
+
continue;
|
|
449
|
+
lines.push(`~ ${key}`);
|
|
450
|
+
lines.push(...diffLines(prettyLines(previousModels[key]), prettyLines(next[key])));
|
|
451
|
+
}
|
|
452
|
+
return lines.length > 0 ? lines.join('\n') : 'no changes';
|
|
453
|
+
}
|
|
454
|
+
/** Render one model entry as a prefixed JSON block. */
|
|
455
|
+
function entryBlock(prefix, key, value) {
|
|
456
|
+
const [first, ...rest] = prettyLines(value);
|
|
457
|
+
return [`${prefix} ${JSON.stringify(key)}: ${first}`, ...rest.map((line) => `${prefix} ${line}`)];
|
|
458
|
+
}
|
|
459
|
+
/** Pretty-print a value as lines. */
|
|
460
|
+
function prettyLines(value) {
|
|
461
|
+
return JSON.stringify(value, null, 2).split('\n');
|
|
462
|
+
}
|
|
463
|
+
/** Line diff with common prefix/suffix trimmed (LCS over the middle). */
|
|
464
|
+
function diffLines(before, after) {
|
|
465
|
+
let start = 0;
|
|
466
|
+
while (start < before.length && start < after.length && before[start] === after[start])
|
|
467
|
+
start++;
|
|
468
|
+
let endBefore = before.length;
|
|
469
|
+
let endAfter = after.length;
|
|
470
|
+
while (endBefore > start &&
|
|
471
|
+
endAfter > start &&
|
|
472
|
+
before[endBefore - 1] === after[endAfter - 1]) {
|
|
473
|
+
endBefore--;
|
|
474
|
+
endAfter--;
|
|
475
|
+
}
|
|
476
|
+
const middleBefore = before.slice(start, endBefore);
|
|
477
|
+
const middleAfter = after.slice(start, endAfter);
|
|
478
|
+
const out = before.slice(0, start).map((line) => ` ${line}`);
|
|
479
|
+
out.push(...emitDiff(middleBefore, middleAfter));
|
|
480
|
+
out.push(...before.slice(endBefore).map((line) => ` ${line}`));
|
|
481
|
+
return out;
|
|
482
|
+
}
|
|
483
|
+
/** Walk the LCS table to emit ` `/`-`/`+` lines for the changed middle. */
|
|
484
|
+
function emitDiff(before, after) {
|
|
485
|
+
const table = lcsTable(before, after);
|
|
486
|
+
const out = [];
|
|
487
|
+
let i = 0;
|
|
488
|
+
let j = 0;
|
|
489
|
+
while (i < before.length && j < after.length) {
|
|
490
|
+
if (before[i] === after[j]) {
|
|
491
|
+
out.push(` ${before[i]}`);
|
|
492
|
+
i++;
|
|
493
|
+
j++;
|
|
494
|
+
}
|
|
495
|
+
else if (table[i + 1][j] >= table[i][j + 1]) {
|
|
496
|
+
out.push(`- ${before[i]}`);
|
|
497
|
+
i++;
|
|
498
|
+
}
|
|
499
|
+
else {
|
|
500
|
+
out.push(`+ ${after[j]}`);
|
|
501
|
+
j++;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
for (; i < before.length; i++)
|
|
505
|
+
out.push(`- ${before[i]}`);
|
|
506
|
+
for (; j < after.length; j++)
|
|
507
|
+
out.push(`+ ${after[j]}`);
|
|
508
|
+
return out;
|
|
509
|
+
}
|
|
510
|
+
/** LCS length table where `table[i][j]` covers `before[i:]` × `after[j:]`. */
|
|
511
|
+
function lcsTable(before, after) {
|
|
512
|
+
const table = Array.from({ length: before.length + 1 }, () => new Array(after.length + 1).fill(0));
|
|
513
|
+
for (let i = before.length - 1; i >= 0; i--) {
|
|
514
|
+
for (let j = after.length - 1; j >= 0; j--) {
|
|
515
|
+
table[i][j] = before[i] === after[j]
|
|
516
|
+
? table[i + 1][j + 1] + 1
|
|
517
|
+
: Math.max(table[i + 1][j], table[i][j + 1]);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
return table;
|
|
521
|
+
}
|
|
522
|
+
//# sourceMappingURL=models-refresh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models-refresh.js","sourceRoot":"","sources":["../src/models-refresh.ts"],"names":[],"mappings":"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"}
|
package/dist/models-sync.d.ts
CHANGED
|
@@ -32,7 +32,7 @@ export declare function getMissingModels(current: string[], upstream: string[]):
|
|
|
32
32
|
*
|
|
33
33
|
* Priority (first match wins):
|
|
34
34
|
* 1. models.dev metadata (if provided and found for modelId)
|
|
35
|
-
* 2. Bundled `models.json` catalog
|
|
35
|
+
* 2. Bundled `assets/models.json` catalog
|
|
36
36
|
* 3. Heuristic title-case of the ID with default limits
|
|
37
37
|
*
|
|
38
38
|
* @param modelId — The upstream model ID (e.g. "glm-5", "kimi-k2.7-code")
|
|
@@ -83,22 +83,18 @@ export declare function syncOpencodeModelsWithUpstream(config: ProxyConfig, conf
|
|
|
83
83
|
/**
|
|
84
84
|
* Extract the opencode-go provider's models from a models.dev API response.
|
|
85
85
|
*
|
|
86
|
-
*
|
|
86
|
+
* Thin delegate: per-provider extraction lives in `models-dev.ts`.
|
|
87
87
|
*
|
|
88
88
|
* @param parsed — Parsed models.dev JSON object (result of `JSON.parse`)
|
|
89
89
|
* @returns Model ID → metadata map, or empty object if provider not found
|
|
90
90
|
*/
|
|
91
91
|
export declare function extractOpencodeGoModels(parsed: Record<string, unknown>): Record<string, Record<string, unknown>>;
|
|
92
92
|
/**
|
|
93
|
-
* Fetch
|
|
93
|
+
* Fetch opencode-go metadata from models.dev.
|
|
94
94
|
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
* @returns Model ID → metadata map, null on failure, empty on missing provider
|
|
95
|
+
* Never throws — returns null on any failure, `{}` when the provider is absent.
|
|
96
|
+
* The TTL cache is shared with every other provider slice.
|
|
99
97
|
*/
|
|
100
98
|
export declare function fetchModelsDevMetadata(): Promise<Record<string, Record<string, unknown>> | null>;
|
|
101
|
-
/**
|
|
102
|
-
* Clear the models.dev in-memory cache (test helper).
|
|
103
|
-
*/
|
|
99
|
+
/** Clear the models.dev in-memory cache (test helper). */
|
|
104
100
|
export declare function resetModelsDevCacheState(): void;
|