@vymalo/opencode-models-info 0.12.0 → 0.14.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/dist/cache.d.ts +23 -23
- package/dist/cache.js +89 -91
- package/dist/cache.js.map +1 -1
- package/dist/config.d.ts +23 -23
- package/dist/config.js +109 -109
- package/dist/config.js.map +1 -1
- package/dist/fetcher.d.ts +9 -9
- package/dist/fetcher.js +76 -70
- package/dist/fetcher.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lib.js +1 -0
- package/dist/lib.js.map +1 -1
- package/dist/logging.d.ts +6 -6
- package/dist/logging.js +58 -62
- package/dist/logging.js.map +1 -1
- package/dist/mapping.d.ts +39 -39
- package/dist/mapping.js +144 -130
- package/dist/mapping.js.map +1 -1
- package/dist/opencode.d.ts +4 -4
- package/dist/opencode.js +70 -69
- package/dist/opencode.js.map +1 -1
- package/dist/plugin.d.ts +25 -25
- package/dist/plugin.js +342 -315
- package/dist/plugin.js.map +1 -1
- package/dist/scheduler.d.ts +16 -16
- package/dist/scheduler.js +55 -57
- package/dist/scheduler.js.map +1 -1
- package/dist/types.d.ts +67 -67
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/package.json +3 -3
package/dist/fetcher.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { FetchModelsResult } from "./types.js";
|
|
2
2
|
export interface FetchOptions {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
url: string;
|
|
4
|
+
headers?: Record<string, string>;
|
|
5
|
+
timeoutMs: number;
|
|
6
|
+
etag?: string;
|
|
7
|
+
fetchImpl?: typeof fetch;
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
* GET the models-info endpoint and return either the parsed entries, a
|
|
11
|
+
* not-modified marker (when the server respects the supplied `If-None-Match`),
|
|
12
|
+
* or an error result. Never throws — the plugin must remain non-fatal.
|
|
13
|
+
*/
|
|
14
14
|
export declare function fetchOpenRouterModels(opts: FetchOptions): Promise<FetchModelsResult>;
|
package/dist/fetcher.js
CHANGED
|
@@ -1,81 +1,87 @@
|
|
|
1
1
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
* GET the models-info endpoint and return either the parsed entries, a
|
|
3
|
+
* not-modified marker (when the server respects the supplied `If-None-Match`),
|
|
4
|
+
* or an error result. Never throws — the plugin must remain non-fatal.
|
|
5
|
+
*/
|
|
6
6
|
export async function fetchOpenRouterModels(opts) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
7
|
+
const impl = opts.fetchImpl ?? fetch;
|
|
8
|
+
const controller = new AbortController();
|
|
9
|
+
const timer = setTimeout(() => controller.abort(), opts.timeoutMs);
|
|
10
|
+
try {
|
|
11
|
+
const headers = {
|
|
12
|
+
accept: "application/json",
|
|
13
|
+
...opts.headers ?? {}
|
|
14
|
+
};
|
|
15
|
+
if (opts.etag) {
|
|
16
|
+
headers["if-none-match"] = opts.etag;
|
|
17
|
+
}
|
|
18
|
+
const response = await impl(opts.url, {
|
|
19
|
+
method: "GET",
|
|
20
|
+
headers,
|
|
21
|
+
signal: controller.signal
|
|
22
|
+
});
|
|
23
|
+
if (response.status === 304) {
|
|
24
|
+
return {
|
|
25
|
+
status: "not-modified",
|
|
26
|
+
etag: opts.etag
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (!response.ok) {
|
|
30
|
+
return {
|
|
31
|
+
status: "error",
|
|
32
|
+
error: `HTTP ${response.status}`
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const body = await response.json();
|
|
36
|
+
const models = normalizeResponse(body);
|
|
37
|
+
if (!models) {
|
|
38
|
+
return {
|
|
39
|
+
status: "error",
|
|
40
|
+
error: "unexpected response shape"
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
status: "ok",
|
|
45
|
+
etag: response.headers.get("etag") ?? undefined,
|
|
46
|
+
models
|
|
47
|
+
};
|
|
48
|
+
} catch (error) {
|
|
49
|
+
return {
|
|
50
|
+
status: "error",
|
|
51
|
+
error: error instanceof Error ? error.message : String(error)
|
|
52
|
+
};
|
|
53
|
+
} finally {
|
|
54
|
+
clearTimeout(timer);
|
|
55
|
+
}
|
|
49
56
|
}
|
|
50
57
|
function normalizeResponse(body) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
if (Array.isArray(body)) {
|
|
59
|
+
return validateFiltered(body);
|
|
60
|
+
}
|
|
61
|
+
if (body && typeof body === "object") {
|
|
62
|
+
const data = body.data;
|
|
63
|
+
if (Array.isArray(data)) {
|
|
64
|
+
return validateFiltered(data);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return undefined;
|
|
61
68
|
}
|
|
62
69
|
/**
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
* Filter to entries with a string `id`, but reject the whole response if a
|
|
71
|
+
* non-empty input came in and every entry was filtered out — that's a parse
|
|
72
|
+
* error, not a legitimate empty catalog, and we don't want to overwrite a
|
|
73
|
+
* previously-good cache with []. An input that was empty to begin with is
|
|
74
|
+
* still a valid (if unusual) response.
|
|
75
|
+
*/
|
|
69
76
|
function validateFiltered(input) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
const filtered = input.filter(isOpenRouterModel);
|
|
78
|
+
if (input.length > 0 && filtered.length === 0) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
return filtered;
|
|
75
82
|
}
|
|
76
83
|
function isOpenRouterModel(value) {
|
|
77
|
-
|
|
78
|
-
typeof value === "object" &&
|
|
79
|
-
typeof value.id === "string");
|
|
84
|
+
return Boolean(value) && typeof value === "object" && typeof value.id === "string";
|
|
80
85
|
}
|
|
86
|
+
|
|
81
87
|
//# sourceMappingURL=fetcher.js.map
|
package/dist/fetcher.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"
|
|
1
|
+
{"mappings":";;;;;AAeA,OAAO,eAAe,sBAAsB,MAAgD;CAC1F,MAAM,OAAO,KAAK,aAAa;CAC/B,MAAM,aAAa,IAAI,gBAAgB;CACvC,MAAM,QAAQ,iBAAiB,WAAW,MAAM,GAAG,KAAK,SAAS;CAEjE,IAAI;EACF,MAAM,UAAkC;GACtC,QAAQ;GACR,GAAI,KAAK,WAAW,CAAC;EACvB;EACA,IAAI,KAAK,MAAM;GACb,QAAQ,mBAAmB,KAAK;EAClC;EAEA,MAAM,WAAW,MAAM,KAAK,KAAK,KAAK;GACpC,QAAQ;GACR;GACA,QAAQ,WAAW;EACrB,CAAC;EAED,IAAI,SAAS,WAAW,KAAK;GAC3B,OAAO;IAAE,QAAQ;IAAgB,MAAM,KAAK;GAAK;EACnD;EAEA,IAAI,CAAC,SAAS,IAAI;GAChB,OAAO;IAAE,QAAQ;IAAS,OAAO,QAAQ,SAAS;GAAS;EAC7D;EAEA,MAAM,OAAQ,MAAM,SAAS,KAAK;EAClC,MAAM,SAAS,kBAAkB,IAAI;EACrC,IAAI,CAAC,QAAQ;GACX,OAAO;IAAE,QAAQ;IAAS,OAAO;GAA4B;EAC/D;EAEA,OAAO;GACL,QAAQ;GACR,MAAM,SAAS,QAAQ,IAAI,MAAM,KAAK;GACtC;EACF;CACF,SAAS,OAAO;EACd,OAAO;GACL,QAAQ;GACR,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EAC9D;CACF,UAAU;EACR,aAAa,KAAK;CACpB;AACF;AAEA,SAAS,kBAAkB,MAA8C;CACvE,IAAI,MAAM,QAAQ,IAAI,GAAG;EACvB,OAAO,iBAAiB,IAAI;CAC9B;CACA,IAAI,QAAQ,OAAO,SAAS,UAAU;EACpC,MAAM,OAAQ,KAAkC;EAChD,IAAI,MAAM,QAAQ,IAAI,GAAG;GACvB,OAAO,iBAAiB,IAAI;EAC9B;CACF;CACA,OAAO;AACT;;;;;;;;AASA,SAAS,iBAAiB,OAAiD;CACzE,MAAM,WAAW,MAAM,OAAO,iBAAiB;CAC/C,IAAI,MAAM,SAAS,KAAK,SAAS,WAAW,GAAG;EAC7C,OAAO;CACT;CACA,OAAO;AACT;AAEA,SAAS,kBAAkB,OAA0C;CACnE,OACE,QAAQ,KAAK,KACb,OAAO,UAAU,YACjB,OAAQ,MAA2B,OAAO;AAE9C","names":[],"sources":["../src/fetcher.ts"],"version":3,"file":"fetcher.js","sourceRoot":""}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"
|
|
1
|
+
{"mappings":";;;AAGA,SAAS,eAAe","names":[],"sources":["../src/index.ts"],"version":3,"file":"index.js","sourceRoot":""}
|
package/dist/lib.js
CHANGED
|
@@ -5,4 +5,5 @@ export { fetchOpenRouterModels } from "./fetcher.js";
|
|
|
5
5
|
export { createJsonConsoleLogger, DEFAULT_LOG_LEVEL, fromOpenCodeLogLevel } from "./logging.js";
|
|
6
6
|
export { mapOpenRouterEntry, mergeIntoModel } from "./mapping.js";
|
|
7
7
|
export { enrichConfig } from "./plugin.js";
|
|
8
|
+
|
|
8
9
|
//# sourceMappingURL=lib.js.map
|
package/dist/lib.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"
|
|
1
|
+
{"mappings":"AAAA,SACE,gCACA,gCAEK;AAEP,SACE,UAEA,gBACA,WACA,uBACK;AAEP,SACE,oBACA,qBACA,wBACK;AAEP,SAAS,6BAAgD;AAEzD,SACE,yBACA,mBACA,4BAIK;AAEP,SACE,oBACA,sBAEK;AAEP,SAGE,oBAEK","names":[],"sources":["../src/lib.ts"],"version":3,"file":"lib.js","sourceRoot":""}
|
package/dist/logging.d.ts
CHANGED
|
@@ -3,14 +3,14 @@ export type { LogLevel } from "./types.js";
|
|
|
3
3
|
export declare const LOG_LEVEL_PRIORITY: Record<LogLevel, number>;
|
|
4
4
|
export declare const DEFAULT_LOG_LEVEL: LogLevel;
|
|
5
5
|
export interface LogFields {
|
|
6
|
-
|
|
6
|
+
[key: string]: unknown;
|
|
7
7
|
}
|
|
8
8
|
export interface Logger {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
trace(event: string, fields?: LogFields): void;
|
|
10
|
+
debug(event: string, fields?: LogFields): void;
|
|
11
|
+
info(event: string, fields?: LogFields): void;
|
|
12
|
+
warn(event: string, fields?: LogFields): void;
|
|
13
|
+
error(event: string, fields?: LogFields): void;
|
|
14
14
|
}
|
|
15
15
|
export declare function createJsonConsoleLogger(minLevel?: LogLevel): Logger;
|
|
16
16
|
export declare function fromOpenCodeLogLevel(value: unknown): LogLevel | undefined;
|
package/dist/logging.js
CHANGED
|
@@ -1,72 +1,68 @@
|
|
|
1
1
|
export const LOG_LEVEL_PRIORITY = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
trace: 5,
|
|
3
|
+
debug: 10,
|
|
4
|
+
info: 20,
|
|
5
|
+
warn: 30,
|
|
6
|
+
error: 40
|
|
7
7
|
};
|
|
8
8
|
export const DEFAULT_LOG_LEVEL = "info";
|
|
9
9
|
function redactFields(fields) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
10
|
+
if (!fields) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
const redacted = {};
|
|
14
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
15
|
+
if (/token|secret|password|authorization/i.test(key)) {
|
|
16
|
+
redacted[key] = "[redacted]";
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
redacted[key] = value;
|
|
20
|
+
}
|
|
21
|
+
return redacted;
|
|
22
22
|
}
|
|
23
23
|
export function createJsonConsoleLogger(minLevel = DEFAULT_LOG_LEVEL) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
24
|
+
const minPriority = LOG_LEVEL_PRIORITY[minLevel];
|
|
25
|
+
const write = (level, event, fields) => {
|
|
26
|
+
if (LOG_LEVEL_PRIORITY[level] < minPriority) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const payload = {
|
|
30
|
+
ts: new Date().toISOString(),
|
|
31
|
+
level,
|
|
32
|
+
event,
|
|
33
|
+
...redactFields(fields) ?? {}
|
|
34
|
+
};
|
|
35
|
+
const line = JSON.stringify(payload);
|
|
36
|
+
if (level === "error") {
|
|
37
|
+
console.error(line);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (level === "warn") {
|
|
41
|
+
console.warn(line);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
console.log(line);
|
|
45
|
+
};
|
|
46
|
+
return {
|
|
47
|
+
trace: (event, fields) => write("trace", event, fields),
|
|
48
|
+
debug: (event, fields) => write("debug", event, fields),
|
|
49
|
+
info: (event, fields) => write("info", event, fields),
|
|
50
|
+
warn: (event, fields) => write("warn", event, fields),
|
|
51
|
+
error: (event, fields) => write("error", event, fields)
|
|
52
|
+
};
|
|
53
53
|
}
|
|
54
54
|
export function fromOpenCodeLogLevel(value) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
case "ERROR":
|
|
67
|
-
return "error";
|
|
68
|
-
default:
|
|
69
|
-
return undefined;
|
|
70
|
-
}
|
|
55
|
+
if (typeof value !== "string") {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
switch (value.toUpperCase()) {
|
|
59
|
+
// DEBUG unlocks the most-verbose `trace` tier (all trace events emit).
|
|
60
|
+
case "DEBUG": return "trace";
|
|
61
|
+
case "INFO": return "info";
|
|
62
|
+
case "WARN": return "warn";
|
|
63
|
+
case "ERROR": return "error";
|
|
64
|
+
default: return undefined;
|
|
65
|
+
}
|
|
71
66
|
}
|
|
67
|
+
|
|
72
68
|
//# sourceMappingURL=logging.js.map
|
package/dist/logging.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"
|
|
1
|
+
{"mappings":"AAIA,OAAO,MAAM,qBAA+C;CAC1D,OAAO;CACP,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;AACT;AAEA,OAAO,MAAM,oBAA8B;AAc3C,SAAS,aAAa,QAA2C;CAC/D,IAAI,CAAC,QAAQ;EACX,OAAO;CACT;CACA,MAAM,WAAsB,CAAC;CAC7B,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,GAAG;EACjD,IAAI,uCAAuC,KAAK,GAAG,GAAG;GACpD,SAAS,OAAO;GAChB;EACF;EACA,SAAS,OAAO;CAClB;CACA,OAAO;AACT;AAEA,OAAO,SAAS,wBAAwB,WAAqB,mBAA2B;CACtF,MAAM,cAAc,mBAAmB;CAEvC,MAAM,SAAS,OAAiB,OAAe,WAA6B;EAC1E,IAAI,mBAAmB,SAAS,aAAa;GAC3C;EACF;EACA,MAAM,UAAU;GACd,IAAI,IAAI,KAAK,CAAC,CAAC,YAAY;GAC3B;GACA;GACA,GAAI,aAAa,MAAM,KAAK,CAAC;EAC/B;EACA,MAAM,OAAO,KAAK,UAAU,OAAO;EACnC,IAAI,UAAU,SAAS;GACrB,QAAQ,MAAM,IAAI;GAClB;EACF;EACA,IAAI,UAAU,QAAQ;GACpB,QAAQ,KAAK,IAAI;GACjB;EACF;EACA,QAAQ,IAAI,IAAI;CAClB;CAEA,OAAO;EACL,QAAQ,OAAO,WAAW,MAAM,SAAS,OAAO,MAAM;EACtD,QAAQ,OAAO,WAAW,MAAM,SAAS,OAAO,MAAM;EACtD,OAAO,OAAO,WAAW,MAAM,QAAQ,OAAO,MAAM;EACpD,OAAO,OAAO,WAAW,MAAM,QAAQ,OAAO,MAAM;EACpD,QAAQ,OAAO,WAAW,MAAM,SAAS,OAAO,MAAM;CACxD;AACF;AAEA,OAAO,SAAS,qBAAqB,OAAsC;CACzE,IAAI,OAAO,UAAU,UAAU;EAC7B,OAAO;CACT;CACA,QAAQ,MAAM,YAAY,GAA1B;;EAEE,KAAK,SACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,SACE,OAAO;CACX;AACF","names":[],"sources":["../src/logging.ts"],"version":3,"file":"logging.js","sourceRoot":""}
|
package/dist/mapping.d.ts
CHANGED
|
@@ -1,50 +1,50 @@
|
|
|
1
1
|
import type { OpenRouterModel } from "./types.js";
|
|
2
2
|
type OpenCodeModality = "text" | "audio" | "image" | "video" | "pdf";
|
|
3
3
|
export interface ModelMetadata {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
4
|
+
name?: string;
|
|
5
|
+
attachment?: boolean;
|
|
6
|
+
reasoning?: boolean;
|
|
7
|
+
temperature?: boolean;
|
|
8
|
+
tool_call?: boolean;
|
|
9
|
+
cost?: {
|
|
10
|
+
input: number;
|
|
11
|
+
output: number;
|
|
12
|
+
cache_read?: number;
|
|
13
|
+
cache_write?: number;
|
|
14
|
+
};
|
|
15
|
+
limit?: {
|
|
16
|
+
context: number;
|
|
17
|
+
output: number;
|
|
18
|
+
};
|
|
19
|
+
modalities?: {
|
|
20
|
+
input: OpenCodeModality[];
|
|
21
|
+
output: OpenCodeModality[];
|
|
22
|
+
};
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
* Pure transformation from an OpenRouter model entry to the subset of
|
|
26
|
+
* OpenCode `ModelConfig` fields we know how to populate. Returns only the
|
|
27
|
+
* fields we can derive; callers do the upstream-wins merge.
|
|
28
|
+
*/
|
|
29
29
|
export declare function mapOpenRouterEntry(entry: OpenRouterModel, overwrite?: ReadonlySet<string>): ModelMetadata;
|
|
30
30
|
/**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
* A model is "text-only" when the source reported modalities and both input
|
|
32
|
+
* and output are exactly `["text"]` — no vision/audio/video/pdf on either
|
|
33
|
+
* side. Undefined `modalities` means the source never told us, so we can't
|
|
34
|
+
* claim text-only (consistent with the true-only / "known" pattern above).
|
|
35
|
+
*/
|
|
36
36
|
export declare function isTextOnlyModality(modalities: ModelMetadata["modalities"]): boolean;
|
|
37
37
|
/**
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
38
|
+
* Merge a derived metadata snapshot onto an existing OpenCode model entry.
|
|
39
|
+
* Upstream wins by default: any field already present is left untouched.
|
|
40
|
+
* Returns the same object reference (mutated) for ergonomic chaining.
|
|
41
|
+
*
|
|
42
|
+
* `overwrite` opts specific fields *out* of upstream-wins, letting the derived
|
|
43
|
+
* (endpoint) value replace one that's already set. This exists because another
|
|
44
|
+
* plugin (e.g. `@vymalo/opencode-oauth2`) may auto-stamp a field such as `name`
|
|
45
|
+
* before this hook runs — to upstream-wins that looks like deliberate user
|
|
46
|
+
* config, so without an opt-out the endpoint's value can never land. A field
|
|
47
|
+
* named in `overwrite` only wins when the derived value is actually present.
|
|
48
|
+
*/
|
|
49
49
|
export declare function mergeIntoModel<T extends Record<string, unknown>>(existing: T, derived: ModelMetadata, overwrite?: ReadonlySet<string>): T;
|
|
50
50
|
export {};
|