@byfriends/oauth 0.1.1 → 0.3.2
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/index.d.mts +11 -1
- package/dist/index.mjs +69 -2
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -40,6 +40,15 @@ declare class ProviderApiError extends Error {
|
|
|
40
40
|
constructor(message: string, status: number);
|
|
41
41
|
}
|
|
42
42
|
declare function fetchModels(baseUrl: string, apiKey: string, fetchImpl?: typeof fetch, signal?: AbortSignal): Promise<ModelInfo[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Lists models from a provider using its native wire-type endpoint. Dispatches
|
|
45
|
+
* per `type` so each protocol gets its correct auth header and response shape.
|
|
46
|
+
* `openai-completions` and `openai_responses` share the OpenAI-compatible
|
|
47
|
+
* `/models` endpoint; `anthropic` uses its native `x-api-key` endpoint with
|
|
48
|
+
* pagination. Other types have dedicated native fetchers (added in
|
|
49
|
+
* later slices).
|
|
50
|
+
*/
|
|
51
|
+
declare function fetchModelsByType(type: string, baseUrl: string, apiKey: string, fetchImpl?: typeof fetch, signal?: AbortSignal): Promise<ModelInfo[]>;
|
|
43
52
|
declare function filterModelsByPrefix(models: ModelInfo[], prefixes?: readonly string[] | undefined): ModelInfo[];
|
|
44
53
|
declare function capabilitiesForModel(model: ModelInfo): string[] | undefined;
|
|
45
54
|
interface ApplyProviderResult {
|
|
@@ -48,6 +57,7 @@ interface ApplyProviderResult {
|
|
|
48
57
|
}
|
|
49
58
|
declare function applyProviderConfig(config: ConfigShape, options: {
|
|
50
59
|
readonly name: string;
|
|
60
|
+
readonly type?: string | undefined;
|
|
51
61
|
readonly baseUrl: string;
|
|
52
62
|
readonly apiKey: string;
|
|
53
63
|
readonly models: readonly ModelInfo[];
|
|
@@ -56,4 +66,4 @@ declare function applyProviderConfig(config: ConfigShape, options: {
|
|
|
56
66
|
}): ApplyProviderResult;
|
|
57
67
|
declare function removeProviderConfig(config: ConfigShape, providerName: string): void;
|
|
58
68
|
//#endregion
|
|
59
|
-
export { type ApplyProviderResult, type ConfigShape, type ModelAlias, type ModelInfo, ProviderApiError, type ProviderConfig, type ServicesConfig, applyProviderConfig, capabilitiesForModel, fetchModels, filterModelsByPrefix, removeProviderConfig };
|
|
69
|
+
export { type ApplyProviderResult, type ConfigShape, type ModelAlias, type ModelInfo, ProviderApiError, type ProviderConfig, type ServicesConfig, applyProviderConfig, capabilitiesForModel, fetchModels, fetchModelsByType, filterModelsByPrefix, removeProviderConfig };
|
package/dist/index.mjs
CHANGED
|
@@ -103,6 +103,9 @@ function firstNonEmptyString(source, keys) {
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
async function fetchModels(baseUrl, apiKey, fetchImpl = fetch, signal) {
|
|
106
|
+
return fetchOpenAICompatModels(baseUrl, apiKey, fetchImpl, signal);
|
|
107
|
+
}
|
|
108
|
+
async function fetchOpenAICompatModels(baseUrl, apiKey, fetchImpl = fetch, signal) {
|
|
106
109
|
const res = await fetchImpl(`${baseUrl.replace(/\/+$/, "")}/models`, {
|
|
107
110
|
headers: {
|
|
108
111
|
Authorization: `Bearer ${apiKey}`,
|
|
@@ -115,6 +118,70 @@ async function fetchModels(baseUrl, apiKey, fetchImpl = fetch, signal) {
|
|
|
115
118
|
if (!isRecord(payload) || !Array.isArray(payload["data"])) throw new Error(`Unexpected models response for ${baseUrl}.`);
|
|
116
119
|
return payload["data"].map((item) => toModelInfo(item)).filter((item) => item !== void 0);
|
|
117
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Lists models from a provider using its native wire-type endpoint. Dispatches
|
|
123
|
+
* per `type` so each protocol gets its correct auth header and response shape.
|
|
124
|
+
* `openai-completions` and `openai_responses` share the OpenAI-compatible
|
|
125
|
+
* `/models` endpoint; `anthropic` uses its native `x-api-key` endpoint with
|
|
126
|
+
* pagination. Other types have dedicated native fetchers (added in
|
|
127
|
+
* later slices).
|
|
128
|
+
*/
|
|
129
|
+
async function fetchModelsByType(type, baseUrl, apiKey, fetchImpl = fetch, signal) {
|
|
130
|
+
switch (type) {
|
|
131
|
+
case "openai-completions":
|
|
132
|
+
case "openai_responses": return fetchOpenAICompatModels(baseUrl, apiKey, fetchImpl, signal);
|
|
133
|
+
case "anthropic": return fetchAnthropicModels(baseUrl, apiKey, fetchImpl, signal);
|
|
134
|
+
default: throw new Error(`fetchModelsByType: unsupported provider type "${type}".`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Anthropic native `/v1/models` listing. Uses `x-api-key` + `anthropic-version`
|
|
139
|
+
* headers (not Bearer). Response is paginated via `has_more` + `last_id`;
|
|
140
|
+
* follow pages by passing `?after_id=<last_id>`. Defensive guards: a page that
|
|
141
|
+
* claims `has_more` but omits `last_id` stops pagination (returns what we have)
|
|
142
|
+
* rather than looping forever; a hard cap (10 pages) also bounds the loop.
|
|
143
|
+
*/
|
|
144
|
+
async function fetchAnthropicModels(baseUrl, apiKey, fetchImpl = fetch, signal) {
|
|
145
|
+
const base = baseUrl.replace(/\/+$/, "");
|
|
146
|
+
const ANTHROPIC_VERSION = "2023-06-01";
|
|
147
|
+
const MAX_PAGES = 10;
|
|
148
|
+
const collected = [];
|
|
149
|
+
let afterId;
|
|
150
|
+
for (let page = 0; page < MAX_PAGES; page += 1) {
|
|
151
|
+
const res = await fetchImpl(afterId === void 0 ? `${base}/models` : `${base}/models?after_id=${encodeURIComponent(afterId)}`, {
|
|
152
|
+
headers: {
|
|
153
|
+
"x-api-key": apiKey,
|
|
154
|
+
"anthropic-version": ANTHROPIC_VERSION,
|
|
155
|
+
Accept: "application/json"
|
|
156
|
+
},
|
|
157
|
+
signal
|
|
158
|
+
});
|
|
159
|
+
if (!res.ok) throw new ProviderApiError(await readApiErrorMessage(res, `Failed to list models (HTTP ${res.status}).`), res.status);
|
|
160
|
+
const payload = await res.json();
|
|
161
|
+
if (!isRecord(payload) || !Array.isArray(payload["data"])) throw new Error(`Unexpected models response for ${baseUrl}.`);
|
|
162
|
+
for (const item of payload["data"]) {
|
|
163
|
+
const info = anthropicModelToInfo(item);
|
|
164
|
+
if (info !== void 0) collected.push(info);
|
|
165
|
+
}
|
|
166
|
+
const hasMore = payload["has_more"] === true;
|
|
167
|
+
const lastId = typeof payload["last_id"] === "string" ? payload["last_id"] : void 0;
|
|
168
|
+
if (!hasMore || lastId === void 0 || lastId.length === 0) break;
|
|
169
|
+
afterId = lastId;
|
|
170
|
+
}
|
|
171
|
+
return collected;
|
|
172
|
+
}
|
|
173
|
+
function anthropicModelToInfo(item) {
|
|
174
|
+
if (!isRecord(item) || typeof item["id"] !== "string" || item["id"].length === 0) return;
|
|
175
|
+
const displayName = item["display_name"];
|
|
176
|
+
return {
|
|
177
|
+
id: item["id"],
|
|
178
|
+
contextLength: 2e5,
|
|
179
|
+
supportsReasoning: true,
|
|
180
|
+
supportsImageIn: true,
|
|
181
|
+
supportsVideoIn: false,
|
|
182
|
+
displayName: typeof displayName === "string" && displayName.length > 0 ? displayName : void 0
|
|
183
|
+
};
|
|
184
|
+
}
|
|
118
185
|
function filterModelsByPrefix(models, prefixes) {
|
|
119
186
|
if (!prefixes || prefixes.length === 0) return models;
|
|
120
187
|
return models.filter((m) => prefixes.some((p) => m.id.startsWith(p)));
|
|
@@ -132,7 +199,7 @@ function applyProviderConfig(config, options) {
|
|
|
132
199
|
const providerKey = options.name;
|
|
133
200
|
const modelKey = `${providerKey}/${options.selectedModel.id}`;
|
|
134
201
|
config.providers[providerKey] = {
|
|
135
|
-
type: "openai-completions",
|
|
202
|
+
type: options.type ?? "openai-completions",
|
|
136
203
|
baseUrl: options.baseUrl,
|
|
137
204
|
apiKey: options.apiKey,
|
|
138
205
|
thinkingEffortKey: options.selectedModel.reasoningEffortKey
|
|
@@ -171,4 +238,4 @@ function removeProviderConfig(config, providerName) {
|
|
|
171
238
|
if (config["defaultProvider"] === providerName) config["defaultProvider"] = void 0;
|
|
172
239
|
}
|
|
173
240
|
//#endregion
|
|
174
|
-
export { ProviderApiError, applyProviderConfig, capabilitiesForModel, fetchModels, filterModelsByPrefix, removeProviderConfig };
|
|
241
|
+
export { ProviderApiError, applyProviderConfig, capabilitiesForModel, fetchModels, fetchModelsByType, filterModelsByPrefix, removeProviderConfig };
|