@hyav/pi-provider 0.1.4 → 0.1.6
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 +14 -0
- package/README.md +3 -1
- package/README.zh-CN.md +3 -1
- package/core/adapter-extensions.ts +22 -12
- package/core/adapter-validation.ts +23 -6
- package/core/catalog-preflight.ts +20 -8
- package/core/diagnostic-auth.ts +103 -0
- package/core/host.ts +26 -4
- package/core/live-check-manager.ts +2 -1
- package/core/official-pricing.ts +39 -17
- package/core/preflight-manager.ts +27 -8
- package/core/provider-registration.ts +131 -9
- package/core/public-adapters.ts +9 -0
- package/core/runtime-config.ts +3 -0
- package/core/runtime.ts +43 -29
- package/core/status-manager.ts +27 -8
- package/core/types.ts +20 -2
- package/index.ts +10 -1
- package/package.json +1 -1
- package/preflight/charm-hyper.ts +2 -1
- package/preflight/deepseek.ts +2 -1
- package/preflight/github-copilot.ts +23 -10
- package/preflight/google.ts +2 -1
- package/preflight/groq.ts +2 -1
- package/preflight/openai-codex.ts +2 -1
- package/preflight/openrouter.ts +2 -1
- package/preflight/vercel-ai-gateway.ts +1 -6
- package/preflight/xai.ts +2 -1
- package/providers/charm-hyper.ts +4 -1
- package/status/anthropic.ts +5 -1
- package/status/charm-hyper.ts +2 -1
- package/status/deepseek.ts +2 -1
- package/status/github-copilot.ts +23 -10
- package/status/groq.ts +2 -1
- package/status/huggingface.ts +2 -1
- package/status/moonshotai.ts +2 -1
- package/status/openai-codex.ts +2 -1
- package/status/opencode-go.ts +2 -1
- package/status/openrouter.ts +2 -1
- package/status/vercel-ai-gateway.ts +2 -1
- package/status/xai.ts +2 -1
package/preflight/openrouter.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PreflightAdapter } from "@hyav/pi-provider";
|
|
2
|
-
import { definePreflightExtension, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
2
|
+
import { definePreflightExtension, hasBaseUrlOrigin, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
3
3
|
import { OPENROUTER_KEY_URL } from "../status/openrouter.ts";
|
|
4
4
|
|
|
5
5
|
export const OPENROUTER_MODELS_URL = "https://openrouter.ai/api/v1/models";
|
|
@@ -79,6 +79,7 @@ export const openRouterPreflightAdapter: PreflightAdapter = {
|
|
|
79
79
|
name: "OpenRouter",
|
|
80
80
|
cacheTtlMs: 30_000,
|
|
81
81
|
requestTimeoutMs: 8_000,
|
|
82
|
+
supportsModel: (model) => hasBaseUrlOrigin(model.baseUrl, OPENROUTER_MODELS_URL),
|
|
82
83
|
async fetch(context) {
|
|
83
84
|
const modelIds = await collectModelIds(context);
|
|
84
85
|
const apiKey = await context.getApiKey();
|
|
@@ -37,11 +37,6 @@ export function createVercelAIGatewayPreflightAdapter(requestTimeoutMs: number):
|
|
|
37
37
|
cacheTtlMs: 30_000,
|
|
38
38
|
requestTimeoutMs,
|
|
39
39
|
async fetch(context): Promise<PreflightSnapshot> {
|
|
40
|
-
const key = await context.getApiKey();
|
|
41
|
-
if (!key || key === "proxy-managed") {
|
|
42
|
-
return { passed: false, checks: ["auth"], updatedAt: context.now() };
|
|
43
|
-
}
|
|
44
|
-
|
|
45
40
|
const response = await context.fetch(VERCEL_MODELS_URL, {
|
|
46
41
|
headers: {
|
|
47
42
|
Accept: "application/json",
|
|
@@ -67,7 +62,7 @@ export function createVercelAIGatewayPreflightAdapter(requestTimeoutMs: number):
|
|
|
67
62
|
|
|
68
63
|
return {
|
|
69
64
|
passed: parseVercelModelIds(payload).has(context.model.id),
|
|
70
|
-
checks: ["endpoint", "
|
|
65
|
+
checks: ["endpoint", "catalog"],
|
|
71
66
|
updatedAt: context.now(),
|
|
72
67
|
httpStatus: response.status,
|
|
73
68
|
};
|
package/preflight/xai.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PreflightAdapter } from "@hyav/pi-provider";
|
|
2
|
-
import { definePreflightExtension, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
2
|
+
import { definePreflightExtension, hasBaseUrlOrigin, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
3
3
|
import { XAI_MODELS_URL } from "../status/xai.ts";
|
|
4
4
|
|
|
5
5
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
@@ -12,6 +12,7 @@ export const xaiPreflightAdapter: PreflightAdapter = {
|
|
|
12
12
|
name: "xAI",
|
|
13
13
|
cacheTtlMs: 30_000,
|
|
14
14
|
requestTimeoutMs: 8_000,
|
|
15
|
+
supportsModel: (model) => hasBaseUrlOrigin(model.baseUrl, XAI_MODELS_URL),
|
|
15
16
|
async fetch(context) {
|
|
16
17
|
const apiKey = await context.getApiKey();
|
|
17
18
|
const authHeaders: Record<string, string> = {
|
package/providers/charm-hyper.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
import {
|
|
10
10
|
defineProviderExtension,
|
|
11
11
|
isProviderDataError,
|
|
12
|
+
MAX_PROVIDER_MODEL_COUNT,
|
|
12
13
|
normalizeProviderModels,
|
|
13
14
|
ProviderDataError,
|
|
14
15
|
withDeadline,
|
|
@@ -242,6 +243,7 @@ function parseCurrentHyperModel(value: unknown): ProviderModelDraft | undefined
|
|
|
242
243
|
|
|
243
244
|
function parseCurrentHyperModels(payload: Record<string, unknown>): ProviderModelDraft[] | undefined {
|
|
244
245
|
if (!Array.isArray(payload.models)) return undefined;
|
|
246
|
+
if (payload.models.length > MAX_PROVIDER_MODEL_COUNT) return [];
|
|
245
247
|
const models: ProviderModelDraft[] = [];
|
|
246
248
|
const seenIds = new Set<string>();
|
|
247
249
|
for (const value of payload.models) {
|
|
@@ -256,7 +258,7 @@ function parseCurrentHyperModels(payload: Record<string, unknown>): ProviderMode
|
|
|
256
258
|
}
|
|
257
259
|
|
|
258
260
|
function parseLegacyHyperModels(payload: Record<string, unknown>): ProviderModelDraft[] {
|
|
259
|
-
if (!Array.isArray(payload.data)) return [];
|
|
261
|
+
if (!Array.isArray(payload.data) || payload.data.length > MAX_PROVIDER_MODEL_COUNT) return [];
|
|
260
262
|
const models: ProviderModelDraft[] = [];
|
|
261
263
|
const seenIds = new Set<string>();
|
|
262
264
|
|
|
@@ -356,6 +358,7 @@ async function discoverHyperModels(
|
|
|
356
358
|
if (models.length === 0) {
|
|
357
359
|
throw new ProviderDataError("Charm Hyper model discovery returned no valid models", "badjson");
|
|
358
360
|
}
|
|
361
|
+
normalizeProviderModels(models);
|
|
359
362
|
return models;
|
|
360
363
|
},
|
|
361
364
|
timeoutMs,
|
package/status/anthropic.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StatusAdapter, StatusEntry, StatusSnapshot } from "@hyav/pi-provider";
|
|
2
|
-
import { defineStatusExtension, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
2
|
+
import { defineStatusExtension, hasBaseUrlOrigin, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Anthropic usage endpoint for subscription quotas (Claude Pro/Max) and extra
|
|
@@ -170,6 +170,10 @@ export function createAnthropicStatusAdapter(
|
|
|
170
170
|
name: "Anthropic",
|
|
171
171
|
cacheTtlMs: 60_000,
|
|
172
172
|
requestTimeoutMs,
|
|
173
|
+
supportsModel: (model) =>
|
|
174
|
+
usageUrl === "" ||
|
|
175
|
+
usageUrl !== DEFAULT_ANTHROPIC_USAGE_URL ||
|
|
176
|
+
hasBaseUrlOrigin(model.baseUrl, "https://api.anthropic.com"),
|
|
173
177
|
async fetch(context): Promise<StatusSnapshot> {
|
|
174
178
|
const key = await context.getApiKey();
|
|
175
179
|
if (!key || key === "proxy-managed") {
|
package/status/charm-hyper.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StatusAdapter, StatusSnapshot } from "@hyav/pi-provider";
|
|
2
|
-
import { defineStatusExtension, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
2
|
+
import { defineStatusExtension, hasBaseUrlOrigin, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
3
3
|
import { hyperJsonHeaders } from "../providers/charm-hyper/constants.ts";
|
|
4
4
|
|
|
5
5
|
const CREDITS_URL = "https://hyper.charm.land/v1/credits";
|
|
@@ -23,6 +23,7 @@ export const hyperStatusAdapter: StatusAdapter = {
|
|
|
23
23
|
name: "Charm Hyper",
|
|
24
24
|
cacheTtlMs: 60_000,
|
|
25
25
|
requestTimeoutMs: 8_000,
|
|
26
|
+
supportsModel: (model) => hasBaseUrlOrigin(model.baseUrl, CREDITS_URL),
|
|
26
27
|
async fetch(context): Promise<StatusSnapshot> {
|
|
27
28
|
const key = await context.getApiKey();
|
|
28
29
|
const headers = new Headers(hyperJsonHeaders({ "Accept-Encoding": "identity" }));
|
package/status/deepseek.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StatusAdapter, StatusSnapshot } from "@hyav/pi-provider";
|
|
2
|
-
import { defineStatusExtension, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
2
|
+
import { defineStatusExtension, hasBaseUrlOrigin, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
3
3
|
|
|
4
4
|
export const DEEPSEEK_BALANCE_URL = "https://api.deepseek.com/user/balance";
|
|
5
5
|
|
|
@@ -41,6 +41,7 @@ export const deepSeekStatusAdapter: StatusAdapter = {
|
|
|
41
41
|
name: "DeepSeek",
|
|
42
42
|
cacheTtlMs: 30_000,
|
|
43
43
|
requestTimeoutMs: 8_000,
|
|
44
|
+
supportsModel: (model) => hasBaseUrlOrigin(model.baseUrl, DEEPSEEK_BALANCE_URL),
|
|
44
45
|
async fetch(context): Promise<StatusSnapshot> {
|
|
45
46
|
const key = await context.getApiKey();
|
|
46
47
|
if (!key || key === "proxy-managed") {
|
package/status/github-copilot.ts
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import type { StatusAdapter, StatusEntry, StatusSnapshot } from "@hyav/pi-provider";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
appendBaseUrlPath,
|
|
4
|
+
authDefinesHeader,
|
|
5
|
+
defineStatusExtension,
|
|
6
|
+
getContextAuth,
|
|
7
|
+
mergeDiagnosticHeaders,
|
|
8
|
+
ProviderDataError,
|
|
9
|
+
parseRetryAfter,
|
|
10
|
+
} from "@hyav/pi-provider";
|
|
3
11
|
|
|
4
12
|
/**
|
|
5
13
|
* GitHub Copilot Individual usage. These endpoints are not part of public
|
|
6
14
|
* GitHub documentation, so payload shapes are parsed defensively and a 404
|
|
7
15
|
* degrades to a single explanatory entry instead of an error state.
|
|
8
16
|
*/
|
|
9
|
-
export const
|
|
17
|
+
export const COPILOT_BASE_URL = "https://api.individual.githubcopilot.com";
|
|
18
|
+
export const COPILOT_USAGE_URL = `${COPILOT_BASE_URL}/usage`;
|
|
10
19
|
|
|
11
20
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
12
21
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -109,17 +118,21 @@ export const githubCopilotStatusAdapter: StatusAdapter = {
|
|
|
109
118
|
cacheTtlMs: 60_000,
|
|
110
119
|
requestTimeoutMs: 8_000,
|
|
111
120
|
async fetch(context): Promise<StatusSnapshot> {
|
|
112
|
-
const
|
|
121
|
+
const auth = await getContextAuth(context);
|
|
122
|
+
const key = auth.apiKey;
|
|
113
123
|
if (!key || key === "proxy-managed") {
|
|
114
124
|
throw new ProviderDataError("GitHub Copilot status requires Copilot OAuth", "auth");
|
|
115
125
|
}
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
126
|
+
const url = appendBaseUrlPath(context.model?.baseUrl ?? auth.baseUrl, "usage", COPILOT_BASE_URL);
|
|
127
|
+
if (!url) throw new ProviderDataError("GitHub Copilot usage endpoint is unavailable", "unsupported");
|
|
128
|
+
const headers = mergeDiagnosticHeaders(auth, {
|
|
129
|
+
Accept: "application/json",
|
|
130
|
+
"Accept-Encoding": "identity",
|
|
131
|
+
"User-Agent": "@hyav/pi-provider",
|
|
132
|
+
});
|
|
133
|
+
if (!authDefinesHeader(auth, "Authorization")) headers.set("Authorization", `Bearer ${key}`);
|
|
134
|
+
const response = await context.fetch(url, {
|
|
135
|
+
headers,
|
|
123
136
|
signal: context.signal,
|
|
124
137
|
});
|
|
125
138
|
if (response.status === 404) {
|
package/status/groq.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StatusAdapter, StatusEntry, StatusSnapshot } from "@hyav/pi-provider";
|
|
2
|
-
import { defineStatusExtension, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
2
|
+
import { defineStatusExtension, hasBaseUrlOrigin, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
3
3
|
import { parseRateLimitWindows } from "../core/ratelimit-headers.ts";
|
|
4
4
|
|
|
5
5
|
export const GROQ_MODELS_URL = "https://api.groq.com/openai/v1/models";
|
|
@@ -29,6 +29,7 @@ export const groqStatusAdapter: StatusAdapter = {
|
|
|
29
29
|
name: "Groq",
|
|
30
30
|
cacheTtlMs: 60_000,
|
|
31
31
|
requestTimeoutMs: 8_000,
|
|
32
|
+
supportsModel: (model) => hasBaseUrlOrigin(model.baseUrl, GROQ_MODELS_URL),
|
|
32
33
|
async fetch(context): Promise<StatusSnapshot> {
|
|
33
34
|
const key = await context.getApiKey();
|
|
34
35
|
if (!key || key === "proxy-managed") {
|
package/status/huggingface.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StatusAdapter, StatusEntry, StatusSnapshot } from "@hyav/pi-provider";
|
|
2
|
-
import { defineStatusExtension, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
2
|
+
import { defineStatusExtension, hasBaseUrlOrigin, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
3
3
|
|
|
4
4
|
export const HF_WHOAMI_URL = "https://huggingface.co/api/whoami-v2";
|
|
5
5
|
|
|
@@ -44,6 +44,7 @@ export const huggingFaceStatusAdapter: StatusAdapter = {
|
|
|
44
44
|
name: "Hugging Face",
|
|
45
45
|
cacheTtlMs: 60_000,
|
|
46
46
|
requestTimeoutMs: 8_000,
|
|
47
|
+
supportsModel: (model) => hasBaseUrlOrigin(model.baseUrl, "https://router.huggingface.co"),
|
|
47
48
|
async fetch(context): Promise<StatusSnapshot> {
|
|
48
49
|
const key = await context.getApiKey();
|
|
49
50
|
if (!key || key === "proxy-managed") {
|
package/status/moonshotai.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StatusAdapter, StatusEntry, StatusSnapshot } from "@hyav/pi-provider";
|
|
2
|
-
import { defineStatusExtension, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
2
|
+
import { defineStatusExtension, hasBaseUrlOrigin, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Moonshot (Kimi) balance checks. International and China platforms keep
|
|
@@ -65,6 +65,7 @@ export function createMoonshotStatusAdapter(config: MoonshotStatusConfig, reques
|
|
|
65
65
|
name: config.name,
|
|
66
66
|
cacheTtlMs: 60_000,
|
|
67
67
|
requestTimeoutMs,
|
|
68
|
+
supportsModel: (model) => hasBaseUrlOrigin(model.baseUrl, config.balanceUrl),
|
|
68
69
|
async fetch(context): Promise<StatusSnapshot> {
|
|
69
70
|
const key = await context.getApiKey();
|
|
70
71
|
if (!key || key === "proxy-managed") {
|
package/status/openai-codex.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StatusAdapter, StatusEntry, StatusSnapshot } from "@hyav/pi-provider";
|
|
2
|
-
import { defineStatusExtension, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
2
|
+
import { defineStatusExtension, hasBaseUrlOrigin, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
3
3
|
|
|
4
4
|
export const CODEX_USAGE_URL = "https://chatgpt.com/backend-api/wham/usage";
|
|
5
5
|
const ACCOUNT_ID_CLAIM = "https://api.openai.com/auth";
|
|
@@ -170,6 +170,7 @@ export const openAICodexStatusAdapter: StatusAdapter = {
|
|
|
170
170
|
name: "OpenAI Codex",
|
|
171
171
|
cacheTtlMs: 60_000,
|
|
172
172
|
requestTimeoutMs: 8_000,
|
|
173
|
+
supportsModel: (model) => hasBaseUrlOrigin(model.baseUrl, CODEX_USAGE_URL),
|
|
173
174
|
async fetch(context): Promise<StatusSnapshot> {
|
|
174
175
|
const key = await context.getApiKey();
|
|
175
176
|
if (!key || key === "proxy-managed") {
|
package/status/opencode-go.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StatusAdapter, StatusEntry, StatusSnapshot } from "@hyav/pi-provider";
|
|
2
|
-
import { defineStatusExtension, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
2
|
+
import { defineStatusExtension, hasBaseUrlOrigin, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
3
3
|
|
|
4
4
|
export const OPENCODE_GO_USAGE_URL = "https://opencode.ai/zen/go/v1/usage";
|
|
5
5
|
|
|
@@ -70,6 +70,7 @@ export const openCodeGoStatusAdapter: StatusAdapter = {
|
|
|
70
70
|
name: "OpenCode Go",
|
|
71
71
|
cacheTtlMs: 60_000,
|
|
72
72
|
requestTimeoutMs: 8_000,
|
|
73
|
+
supportsModel: (model) => hasBaseUrlOrigin(model.baseUrl, OPENCODE_GO_USAGE_URL),
|
|
73
74
|
async fetch(context): Promise<StatusSnapshot> {
|
|
74
75
|
const key = await context.getApiKey();
|
|
75
76
|
if (!key || key === "proxy-managed") {
|
package/status/openrouter.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StatusAdapter, StatusEntry, StatusSnapshot } from "@hyav/pi-provider";
|
|
2
|
-
import { defineStatusExtension, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
2
|
+
import { defineStatusExtension, hasBaseUrlOrigin, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
3
3
|
|
|
4
4
|
export const OPENROUTER_KEY_URL = "https://openrouter.ai/api/v1/auth/key";
|
|
5
5
|
export const OPENROUTER_CREDITS_URL = "https://openrouter.ai/api/v1/credits";
|
|
@@ -109,6 +109,7 @@ export const openRouterStatusAdapter: StatusAdapter = {
|
|
|
109
109
|
name: "OpenRouter",
|
|
110
110
|
cacheTtlMs: 60_000,
|
|
111
111
|
requestTimeoutMs: 8_000,
|
|
112
|
+
supportsModel: (model) => hasBaseUrlOrigin(model.baseUrl, OPENROUTER_KEY_URL),
|
|
112
113
|
async fetch(context): Promise<StatusSnapshot> {
|
|
113
114
|
const key = await context.getApiKey();
|
|
114
115
|
if (!key || key === "proxy-managed") {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StatusAdapter, StatusSnapshot } from "@hyav/pi-provider";
|
|
2
|
-
import { defineStatusExtension, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
2
|
+
import { defineStatusExtension, hasBaseUrlOrigin, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
3
3
|
import { VERCEL_PROVIDER_ID } from "./vercel-ai-gateway/constants.ts";
|
|
4
4
|
|
|
5
5
|
export const VERCEL_CREDITS_URL = "https://ai-gateway.vercel.sh/v1/credits";
|
|
@@ -41,6 +41,7 @@ export function createVercelAIGatewayStatusAdapter(requestTimeoutMs: number): St
|
|
|
41
41
|
name: "Vercel AI Gateway",
|
|
42
42
|
cacheTtlMs: 30_000,
|
|
43
43
|
requestTimeoutMs,
|
|
44
|
+
supportsModel: (model) => hasBaseUrlOrigin(model.baseUrl, VERCEL_CREDITS_URL),
|
|
44
45
|
async fetch(context): Promise<StatusSnapshot> {
|
|
45
46
|
const key = await context.getApiKey();
|
|
46
47
|
if (!key || key === "proxy-managed") {
|
package/status/xai.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StatusAdapter, StatusEntry, StatusSnapshot } from "@hyav/pi-provider";
|
|
2
|
-
import { defineStatusExtension, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
2
|
+
import { defineStatusExtension, hasBaseUrlOrigin, ProviderDataError, parseRetryAfter } from "@hyav/pi-provider";
|
|
3
3
|
import { parseRateLimitWindows } from "../core/ratelimit-headers.ts";
|
|
4
4
|
|
|
5
5
|
export const XAI_MODELS_URL = "https://api.x.ai/v1/models";
|
|
@@ -21,6 +21,7 @@ export const xaiStatusAdapter: StatusAdapter = {
|
|
|
21
21
|
name: "xAI",
|
|
22
22
|
cacheTtlMs: 60_000,
|
|
23
23
|
requestTimeoutMs: 8_000,
|
|
24
|
+
supportsModel: (model) => hasBaseUrlOrigin(model.baseUrl, XAI_MODELS_URL),
|
|
24
25
|
async fetch(context): Promise<StatusSnapshot> {
|
|
25
26
|
const key = await context.getApiKey();
|
|
26
27
|
if (!key || key === "proxy-managed") {
|