@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.0",
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.0",
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 { validateOpenAICompatibleApiKey } from "./api-key-validation";
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 VALIDATION_MODEL = "openai/gpt-4o-mini";
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 validateOpenAICompatibleApiKey({
43
+ await validateApiKeyAgainstModelsEndpoint({
44
44
  provider: "NanoGPT",
45
45
  apiKey: trimmed,
46
- baseUrl: API_BASE_URL,
47
- model: VALIDATION_MODEL,
46
+ modelsUrl: MODELS_URL,
48
47
  signal: options.signal,
49
48
  });
50
49