@oh-my-pi/pi-ai 12.14.0 → 12.14.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-ai",
|
|
3
|
-
"version": "12.14.
|
|
3
|
+
"version": "12.14.2",
|
|
4
4
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"@connectrpc/connect-node": "^2.1.1",
|
|
64
64
|
"@google/genai": "^1.41.0",
|
|
65
65
|
"@mistralai/mistralai": "^1.14.0",
|
|
66
|
-
"@oh-my-pi/pi-utils": "12.14.
|
|
66
|
+
"@oh-my-pi/pi-utils": "12.14.2",
|
|
67
67
|
"@sinclair/typebox": "^0.34.48",
|
|
68
68
|
"@smithy/node-http-handler": "^4.4.10",
|
|
69
69
|
"ajv": "^8.18.0",
|
|
@@ -6,6 +6,13 @@ type OpenAICompatibleValidationOptions = {
|
|
|
6
6
|
signal?: AbortSignal;
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
+
type ModelListValidationOptions = {
|
|
10
|
+
provider: string;
|
|
11
|
+
apiKey: string;
|
|
12
|
+
modelsUrl: string;
|
|
13
|
+
signal?: AbortSignal;
|
|
14
|
+
};
|
|
15
|
+
|
|
9
16
|
const VALIDATION_TIMEOUT_MS = 15_000;
|
|
10
17
|
|
|
11
18
|
/**
|
|
@@ -48,3 +55,38 @@ export async function validateOpenAICompatibleApiKey(options: OpenAICompatibleVa
|
|
|
48
55
|
: `${options.provider} API key validation failed (${response.status})`;
|
|
49
56
|
throw new Error(message);
|
|
50
57
|
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Validate an API key against a provider models endpoint.
|
|
61
|
+
*
|
|
62
|
+
* Useful for providers where access to specific models may vary by plan and
|
|
63
|
+
* should not block key validation.
|
|
64
|
+
*/
|
|
65
|
+
export async function validateApiKeyAgainstModelsEndpoint(options: ModelListValidationOptions): Promise<void> {
|
|
66
|
+
const timeoutSignal = AbortSignal.timeout(VALIDATION_TIMEOUT_MS);
|
|
67
|
+
const signal = options.signal ? AbortSignal.any([options.signal, timeoutSignal]) : timeoutSignal;
|
|
68
|
+
|
|
69
|
+
const response = await fetch(options.modelsUrl, {
|
|
70
|
+
method: "GET",
|
|
71
|
+
headers: {
|
|
72
|
+
Authorization: `Bearer ${options.apiKey}`,
|
|
73
|
+
},
|
|
74
|
+
signal,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
if (response.ok) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let details = "";
|
|
82
|
+
try {
|
|
83
|
+
details = (await response.text()).trim();
|
|
84
|
+
} catch {
|
|
85
|
+
// ignore body parse errors, status is enough
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const message = details
|
|
89
|
+
? `${options.provider} API key validation failed (${response.status}): ${details}`
|
|
90
|
+
: `${options.provider} API key validation failed (${response.status})`;
|
|
91
|
+
throw new Error(message);
|
|
92
|
+
}
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
* 3. Paste key into CLI
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { validateApiKeyAgainstModelsEndpoint } from "./api-key-validation";
|
|
12
12
|
import type { OAuthController } from "./types";
|
|
13
13
|
|
|
14
14
|
const AUTH_URL = "https://nano-gpt.com/api";
|
|
15
15
|
const API_BASE_URL = "https://nano-gpt.com/api/v1";
|
|
16
|
-
const
|
|
16
|
+
const MODELS_URL = `${API_BASE_URL}/models`;
|
|
17
17
|
|
|
18
18
|
export async function loginNanoGPT(options: OAuthController): Promise<string> {
|
|
19
19
|
if (!options.onPrompt) {
|
|
@@ -40,11 +40,10 @@ export async function loginNanoGPT(options: OAuthController): Promise<string> {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
options.onProgress?.("Validating API key...");
|
|
43
|
-
await
|
|
43
|
+
await validateApiKeyAgainstModelsEndpoint({
|
|
44
44
|
provider: "NanoGPT",
|
|
45
45
|
apiKey: trimmed,
|
|
46
|
-
|
|
47
|
-
model: VALIDATION_MODEL,
|
|
46
|
+
modelsUrl: MODELS_URL,
|
|
48
47
|
signal: options.signal,
|
|
49
48
|
});
|
|
50
49
|
|