@rigelbuild/omp-catalog 18.0.3
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/CHANGELOG.md +1204 -0
- package/LICENSE +22 -0
- package/README.md +43 -0
- package/THIRD-PARTY-NOTICES.txt +22909 -0
- package/dist/types/build.d.ts +19 -0
- package/dist/types/compat/anthropic.d.ts +18 -0
- package/dist/types/compat/apply.d.ts +7 -0
- package/dist/types/compat/bedrock.d.ts +3 -0
- package/dist/types/compat/devin.d.ts +9 -0
- package/dist/types/compat/openai.d.ts +28 -0
- package/dist/types/discovery/antigravity.d.ts +70 -0
- package/dist/types/discovery/codex.d.ts +36 -0
- package/dist/types/discovery/cursor-proto.d.ts +5368 -0
- package/dist/types/discovery/cursor.d.ts +23 -0
- package/dist/types/discovery/devin-proto.d.ts +1549 -0
- package/dist/types/discovery/devin.d.ts +24 -0
- package/dist/types/discovery/gemini-cli.d.ts +33 -0
- package/dist/types/discovery/gemini.d.ts +25 -0
- package/dist/types/discovery/gitlab-duo-workflow.d.ts +30 -0
- package/dist/types/discovery/index.d.ts +7 -0
- package/dist/types/discovery/openai-compatible.d.ts +89 -0
- package/dist/types/discovery/protobuf.d.ts +102 -0
- package/dist/types/effort.d.ts +10 -0
- package/dist/types/fireworks-model-id.d.ts +23 -0
- package/dist/types/hosts.d.ts +169 -0
- package/dist/types/identity/bundled.d.ts +3 -0
- package/dist/types/identity/classify.d.ts +69 -0
- package/dist/types/identity/dialect.d.ts +3 -0
- package/dist/types/identity/family.d.ts +239 -0
- package/dist/types/identity/id.d.ts +12 -0
- package/dist/types/identity/index.d.ts +8 -0
- package/dist/types/identity/markers.d.ts +4 -0
- package/dist/types/identity/priority.d.ts +1 -0
- package/dist/types/identity/reference.d.ts +29 -0
- package/dist/types/index.d.ts +19 -0
- package/dist/types/model-cache.d.ts +23 -0
- package/dist/types/model-manager.d.ts +77 -0
- package/dist/types/model-thinking.d.ts +70 -0
- package/dist/types/model-tokenizer.d.ts +8 -0
- package/dist/types/models.d.ts +14 -0
- package/dist/types/openai-pricing.d.ts +17 -0
- package/dist/types/provider-models/bundled-references.d.ts +13 -0
- package/dist/types/provider-models/cache-provider-id.d.ts +11 -0
- package/dist/types/provider-models/descriptor-types.d.ts +76 -0
- package/dist/types/provider-models/descriptors.d.ts +505 -0
- package/dist/types/provider-models/google.d.ts +29 -0
- package/dist/types/provider-models/index.d.ts +7 -0
- package/dist/types/provider-models/ollama.d.ts +22 -0
- package/dist/types/provider-models/openai-compat.d.ts +646 -0
- package/dist/types/provider-models/special.d.ts +53 -0
- package/dist/types/types.d.ts +876 -0
- package/dist/types/utils.d.ts +20 -0
- package/dist/types/variant-collapse.d.ts +137 -0
- package/dist/types/wire/alibaba-token-plan.d.ts +22 -0
- package/dist/types/wire/codex.d.ts +66 -0
- package/dist/types/wire/coreweave.d.ts +12 -0
- package/dist/types/wire/gemini-headers.d.ts +62 -0
- package/dist/types/wire/github-copilot.d.ts +47 -0
- package/dist/types/wire/image-fetchers.d.ts +76 -0
- package/package.json +102 -0
- package/src/build.ts +103 -0
- package/src/compat/anthropic.ts +179 -0
- package/src/compat/apply.ts +15 -0
- package/src/compat/bedrock.ts +153 -0
- package/src/compat/devin.ts +12 -0
- package/src/compat/openai.ts +864 -0
- package/src/discovery/antigravity.ts +257 -0
- package/src/discovery/codex.ts +456 -0
- package/src/discovery/cursor-proto.ts +8329 -0
- package/src/discovery/cursor.ts +409 -0
- package/src/discovery/devin-proto.ts +2037 -0
- package/src/discovery/devin.ts +152 -0
- package/src/discovery/gemini-cli.ts +198 -0
- package/src/discovery/gemini.ts +260 -0
- package/src/discovery/gitlab-duo-workflow.ts +859 -0
- package/src/discovery/index.ts +7 -0
- package/src/discovery/openai-compatible.ts +266 -0
- package/src/discovery/protobuf.ts +1073 -0
- package/src/effort.ts +18 -0
- package/src/fireworks-model-id.ts +50 -0
- package/src/hosts.ts +178 -0
- package/src/identity/bundled.ts +28 -0
- package/src/identity/classify.ts +242 -0
- package/src/identity/dialect.ts +42 -0
- package/src/identity/family.ts +477 -0
- package/src/identity/id.ts +81 -0
- package/src/identity/index.ts +8 -0
- package/src/identity/markers.ts +49 -0
- package/src/identity/priority.ts +59 -0
- package/src/identity/reference.ts +167 -0
- package/src/index.ts +19 -0
- package/src/model-cache.ts +346 -0
- package/src/model-manager.ts +683 -0
- package/src/model-thinking.ts +925 -0
- package/src/model-tokenizer.ts +75 -0
- package/src/models.json +304657 -0
- package/src/models.json.d.ts +9 -0
- package/src/models.ts +108 -0
- package/src/openai-pricing.ts +29 -0
- package/src/provider-models/bundled-references.ts +87 -0
- package/src/provider-models/cache-provider-id.ts +97 -0
- package/src/provider-models/descriptor-types.ts +85 -0
- package/src/provider-models/descriptors.ts +585 -0
- package/src/provider-models/google.ts +117 -0
- package/src/provider-models/index.ts +7 -0
- package/src/provider-models/ollama.ts +204 -0
- package/src/provider-models/openai-compat.ts +6405 -0
- package/src/provider-models/special.ts +213 -0
- package/src/types.ts +1032 -0
- package/src/utils.ts +69 -0
- package/src/variant-collapse.ts +1555 -0
- package/src/wire/alibaba-token-plan.ts +54 -0
- package/src/wire/codex.ts +117 -0
- package/src/wire/coreweave.ts +51 -0
- package/src/wire/gemini-headers.ts +135 -0
- package/src/wire/github-copilot.ts +147 -0
- package/src/wire/image-fetchers.ts +159 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { type } from "@rigelbuild/omp-omptype";
|
|
2
|
+
import type { Api, FetchImpl, ModelSpec, Provider } from "../types";
|
|
3
|
+
import { discoveryFetch } from "../utils";
|
|
4
|
+
|
|
5
|
+
const MODELS_PATH = "/models";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Default hard deadline applied to an OpenAI-compatible `/models` probe when
|
|
9
|
+
* the caller supplies neither an `AbortSignal` nor an explicit `timeoutMs`.
|
|
10
|
+
*
|
|
11
|
+
* Built-in provider model managers (openrouter, xAI, DeepSeek, …) call
|
|
12
|
+
* {@link fetchOpenAICompatibleModels} with no timeout, so without this bound a
|
|
13
|
+
* stalled endpoint left the request pending forever and blocked startup's
|
|
14
|
+
* awaited `resolveModelDiscoveryFallback` discovery pass indefinitely
|
|
15
|
+
* (issue #8315). 10s matches the coding-agent's remote-discovery budget.
|
|
16
|
+
*/
|
|
17
|
+
export const DEFAULT_OPENAI_COMPATIBLE_DISCOVERY_TIMEOUT_MS = 10_000;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Uses a cancellable timer rather than the native abort-timeout helper so
|
|
21
|
+
* successful fast discovery requests do not leave armed timeout signals for
|
|
22
|
+
* concurrent GC to trip over later.
|
|
23
|
+
*/
|
|
24
|
+
async function withOpenAICompatibleDiscoveryTimeout<T>(
|
|
25
|
+
timeoutMs: number,
|
|
26
|
+
run: (signal: AbortSignal) => Promise<T>,
|
|
27
|
+
): Promise<T> {
|
|
28
|
+
const controller = new AbortController();
|
|
29
|
+
const timer = setTimeout(
|
|
30
|
+
() => controller.abort(new DOMException("The operation timed out.", "TimeoutError")),
|
|
31
|
+
timeoutMs,
|
|
32
|
+
);
|
|
33
|
+
try {
|
|
34
|
+
return await run(controller.signal);
|
|
35
|
+
} finally {
|
|
36
|
+
clearTimeout(timer);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Minimal OpenAI-style model entry shape consumed by discovery.
|
|
42
|
+
*
|
|
43
|
+
* Providers may return additional fields; this type only captures
|
|
44
|
+
* fields that are useful for generic normalization.
|
|
45
|
+
*/
|
|
46
|
+
export interface OpenAICompatibleModelRecord {
|
|
47
|
+
id?: unknown;
|
|
48
|
+
name?: unknown;
|
|
49
|
+
object?: unknown;
|
|
50
|
+
owned_by?: unknown;
|
|
51
|
+
[key: string]: unknown;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Tolerant envelope for OpenAI-compatible `/models` responses.
|
|
56
|
+
*
|
|
57
|
+
* Common providers return `{ data: [...] }`, but variants such as
|
|
58
|
+
* `{ models: [...] }`, `{ result: [...] }`, or direct arrays are also
|
|
59
|
+
* accepted during extraction.
|
|
60
|
+
*/
|
|
61
|
+
export interface OpenAICompatibleModelsEnvelope {
|
|
62
|
+
data?: unknown;
|
|
63
|
+
models?: unknown;
|
|
64
|
+
result?: unknown;
|
|
65
|
+
items?: unknown;
|
|
66
|
+
[key: string]: unknown;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const openAICompatibleModelRecordSchema = type({
|
|
70
|
+
id: "string >= 1",
|
|
71
|
+
"name?": "string | null",
|
|
72
|
+
"object?": "unknown",
|
|
73
|
+
"owned_by?": "unknown",
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const openAICompatibleModelsEnvelopeSchema = type({
|
|
77
|
+
"data?": "unknown",
|
|
78
|
+
"models?": "unknown",
|
|
79
|
+
"result?": "unknown",
|
|
80
|
+
"items?": "unknown",
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const openAICompatibleModelsPayloadSchema = type("unknown[]").or(openAICompatibleModelsEnvelopeSchema);
|
|
84
|
+
|
|
85
|
+
type ParsedOpenAICompatibleModelRecord = typeof openAICompatibleModelRecordSchema.infer;
|
|
86
|
+
/**
|
|
87
|
+
* Context passed to custom OpenAI-compatible model mappers.
|
|
88
|
+
*/
|
|
89
|
+
export interface OpenAICompatibleModelMapperContext<TApi extends Api> {
|
|
90
|
+
api: TApi;
|
|
91
|
+
provider: Provider;
|
|
92
|
+
baseUrl: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Options for fetching and normalizing OpenAI-compatible `/models` catalogs.
|
|
97
|
+
*/
|
|
98
|
+
export interface FetchOpenAICompatibleModelsOptions<TApi extends Api> {
|
|
99
|
+
/** API type assigned to normalized models. */
|
|
100
|
+
api: TApi;
|
|
101
|
+
/** Provider id assigned to normalized models. */
|
|
102
|
+
provider: Provider;
|
|
103
|
+
/** Provider base URL used for both fetch and normalized model records. */
|
|
104
|
+
baseUrl: string;
|
|
105
|
+
/** Optional bearer token for Authorization header. */
|
|
106
|
+
apiKey?: string;
|
|
107
|
+
/** Additional request headers. */
|
|
108
|
+
headers?: Record<string, string>;
|
|
109
|
+
/** Optional AbortSignal for request cancellation; caller owns its lifecycle. */
|
|
110
|
+
signal?: AbortSignal;
|
|
111
|
+
/**
|
|
112
|
+
* Optional cancellable request timeout used when `signal` is omitted.
|
|
113
|
+
* Defaults to {@link DEFAULT_OPENAI_COMPATIBLE_DISCOVERY_TIMEOUT_MS} so a
|
|
114
|
+
* stalled endpoint can never hang discovery indefinitely.
|
|
115
|
+
*/
|
|
116
|
+
timeoutMs?: number;
|
|
117
|
+
/** Optional fetch implementation override for testing/custom runtimes. */
|
|
118
|
+
fetch?: FetchImpl;
|
|
119
|
+
/**
|
|
120
|
+
* Optional post-normalization filter.
|
|
121
|
+
* Return false to skip a model.
|
|
122
|
+
*/
|
|
123
|
+
filterModel?: (entry: OpenAICompatibleModelRecord, model: ModelSpec<TApi>) => boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Optional mapper override for provider-specific quirks.
|
|
126
|
+
* Return null to skip a model.
|
|
127
|
+
*/
|
|
128
|
+
mapModel?: (
|
|
129
|
+
entry: OpenAICompatibleModelRecord,
|
|
130
|
+
defaults: ModelSpec<TApi>,
|
|
131
|
+
context: OpenAICompatibleModelMapperContext<TApi>,
|
|
132
|
+
) => ModelSpec<TApi> | null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Fetches and normalizes an OpenAI-compatible `/models` catalog.
|
|
137
|
+
*
|
|
138
|
+
* Returns `null` on transport/protocol failures.
|
|
139
|
+
* Returns `[]` only when the endpoint responds successfully with no usable models.
|
|
140
|
+
*/
|
|
141
|
+
export async function fetchOpenAICompatibleModels<TApi extends Api>(
|
|
142
|
+
options: FetchOpenAICompatibleModelsOptions<TApi>,
|
|
143
|
+
): Promise<ModelSpec<TApi>[] | null> {
|
|
144
|
+
const baseUrl = normalizeBaseUrl(options.baseUrl);
|
|
145
|
+
if (!baseUrl) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const requestHeaders: Record<string, string> = {
|
|
150
|
+
Accept: "application/json",
|
|
151
|
+
...options.headers,
|
|
152
|
+
};
|
|
153
|
+
if (options.apiKey) {
|
|
154
|
+
requestHeaders.Authorization = `Bearer ${options.apiKey}`;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const fetchImpl = discoveryFetch(options.fetch);
|
|
158
|
+
const fetchPayload = async (signal?: AbortSignal): Promise<unknown | null> => {
|
|
159
|
+
let response: Response;
|
|
160
|
+
try {
|
|
161
|
+
response = await fetchImpl(`${baseUrl}${MODELS_PATH}`, {
|
|
162
|
+
method: "GET",
|
|
163
|
+
headers: requestHeaders,
|
|
164
|
+
signal,
|
|
165
|
+
});
|
|
166
|
+
} catch {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (!response.ok) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
return await response.json();
|
|
176
|
+
} catch {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
const payload =
|
|
181
|
+
options.signal !== undefined
|
|
182
|
+
? await fetchPayload(options.signal)
|
|
183
|
+
: await withOpenAICompatibleDiscoveryTimeout(
|
|
184
|
+
options.timeoutMs ?? DEFAULT_OPENAI_COMPATIBLE_DISCOVERY_TIMEOUT_MS,
|
|
185
|
+
fetchPayload,
|
|
186
|
+
);
|
|
187
|
+
if (payload === null) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const entries = extractModelEntries(payload);
|
|
192
|
+
if (entries === null) {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const context: OpenAICompatibleModelMapperContext<TApi> = {
|
|
197
|
+
api: options.api,
|
|
198
|
+
provider: options.provider,
|
|
199
|
+
baseUrl,
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const deduped = new Map<string, ModelSpec<TApi>>();
|
|
203
|
+
for (const entry of entries) {
|
|
204
|
+
const defaults: ModelSpec<TApi> = {
|
|
205
|
+
id: entry.id,
|
|
206
|
+
name: typeof entry.name === "string" && entry.name.length > 0 ? entry.name : entry.id,
|
|
207
|
+
api: options.api,
|
|
208
|
+
provider: options.provider,
|
|
209
|
+
baseUrl,
|
|
210
|
+
reasoning: false,
|
|
211
|
+
input: ["text"],
|
|
212
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
213
|
+
contextWindow: null,
|
|
214
|
+
maxTokens: null,
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
// `mapModel` returning null skips the entry (documented contract); only a
|
|
218
|
+
// missing mapper falls back to the defaults.
|
|
219
|
+
const mapped = options.mapModel ? options.mapModel(entry, defaults, context) : defaults;
|
|
220
|
+
if (!mapped || typeof mapped.id !== "string" || mapped.id.length === 0) {
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
if (options.filterModel && !options.filterModel(entry, mapped)) {
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
deduped.set(mapped.id, mapped);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return Array.from(deduped.values()).sort((left, right) => left.id.localeCompare(right.id));
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function normalizeBaseUrl(baseUrl: string): string {
|
|
233
|
+
const trimmed = baseUrl.trim();
|
|
234
|
+
if (!trimmed) {
|
|
235
|
+
return "";
|
|
236
|
+
}
|
|
237
|
+
return trimmed.endsWith("/") ? trimmed.slice(0, -1) : trimmed;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function extractModelEntries(payload: unknown): ParsedOpenAICompatibleModelRecord[] | null {
|
|
241
|
+
return extractModelEntriesFromNode(payload);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function extractModelEntriesFromNode(node: unknown): ParsedOpenAICompatibleModelRecord[] | null {
|
|
245
|
+
const parsedPayload = openAICompatibleModelsPayloadSchema(node);
|
|
246
|
+
if (parsedPayload instanceof type.errors) {
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
if (Array.isArray(parsedPayload)) {
|
|
250
|
+
const parsedEntries = parsedPayload
|
|
251
|
+
.map(entry => openAICompatibleModelRecordSchema(entry))
|
|
252
|
+
.flatMap(entry => (entry instanceof type.errors ? [] : [entry]));
|
|
253
|
+
return parsedEntries;
|
|
254
|
+
}
|
|
255
|
+
for (const candidate of [parsedPayload.data, parsedPayload.models, parsedPayload.result, parsedPayload.items]) {
|
|
256
|
+
if (candidate === undefined) {
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
const nested = extractModelEntriesFromNode(candidate);
|
|
260
|
+
if (nested !== null) {
|
|
261
|
+
return nested;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return null;
|
|
266
|
+
}
|