-
Notifications
You must be signed in to change notification settings - Fork 202
feat(backend): support OpenAI-compatible gateways for key verification #153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -254,11 +254,21 @@ export async function verifyOpenRouterApiKey(apiKey: string): Promise<void> { | |
|
|
||
| await withFetchTimeout( | ||
| async (signal) => { | ||
| const response = await fetch(`${baseUrl}/key`, { | ||
| let response = await fetch(`${baseUrl}/key`, { | ||
| headers: { Authorization: `Bearer ${apiKey}` }, | ||
| signal, | ||
| }); | ||
|
|
||
| // OpenAI-compatible gateways that don't implement OpenRouter's `/key` | ||
| // endpoint (e.g. OrcaRouter) can still be verified with a lightweight | ||
| // authenticated request — `/models` returns 401 for invalid keys. | ||
| if (response.status === 404) { | ||
| response = await fetch(`${baseUrl}/models`, { | ||
| headers: { Authorization: `Bearer ${apiKey}` }, | ||
| signal, | ||
| }); | ||
| } | ||
|
Comment on lines
+265
to
+270
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- backend/src/local-credentials.ts ---'
sed -n '220,300p' backend/src/local-credentials.ts
printf '%s\n' '--- backend/src/index.ts ---'
sed -n '730,790p' backend/src/index.ts
printf '%s\n' '--- relevant gateway/model references ---'
rg -n -i '(/key|/models|gateway|local-credentials|baseUrl|apiKey)' backend/src backend README.md 2>/dev/null | head -n 250Repository: tinyfish-io/bigset-oss Length of output: 27187 🌐 Web query:
💡 Result: For the OpenRouter API, an invalid or missing API key typically triggers an HTTP 401 Unauthorized status code [1][2][3]. According to official OpenRouter documentation, the following details apply to authentication-related errors: 1. HTTP Status Code: 401 Unauthorized [1][2][3]. 2. Error Cause: This status indicates that the API key is missing, invalid, or has been revoked [1][2]. 3. Canonical Error Type: Failed authentication attempts are categorized under the authentication error type [1][2]. 4. Response Format: When this error occurs, the API typically returns a JSON response containing an error object with a code and a message (e.g., Missing Authentication header) [3]. If you are encountering errors while using the /key endpoint (typically used to verify key status or retrieve key information), the API will similarly reject requests that do not provide valid authentication credentials with a 401 status [3]. If a key is valid but lacks the necessary permissions or is blocked by a guardrail, the API will return a 403 Forbidden status [1][2]. If your key is valid but has insufficient credits, you will receive a 402 Payment Required status [1][2]. Citations:
🌐 Web query:
💡 Result: When accessing the OrcaRouter API, including the /v1/models endpoint, an invalid or missing API key results in an HTTP 401 Unauthorized status [1]. For authentication, OrcaRouter requires that you pass your API key (which follows the format sk-orca-...) in the Authorization header using the Bearer scheme [2][3]: Authorization: Bearer sk-orca-... Additional details regarding OrcaRouter API errors and status codes include: 1. Authentication Errors: HTTP 401 is specifically returned for missing or invalid API keys [1]. 2. Other Common Status Codes: - 400 Bad Request: Used for invalid parameters, missing required fields, or schema violations [1]. - 403 Forbidden: Returned for insufficient quota or when a key lacks permission to access a specific model [1]. - 404 Not Found: Returned when the requested endpoint or model does not exist [1]. - 429 Too Many Requests: Indicates that rate limits have been exceeded; the response will include a Retry-After header [1]. - 502 Bad Gateway: Occurs when all upstream provider attempts (including fallback chains) fail [1]. - 503 Service Unavailable: Returned if the requested model is temporarily unavailable upstream [1]. If you are experiencing issues with the /v1/models endpoint, ensure that your base URL is correctly configured as https://api.orcarouter.ai/v1 [2][4]. Misconfigured base URLs (e.g., missing /v1 or adding extra path components) are a common source of routing errors [5]. Citations:
🏁 Script executed: #!/bin/bash
set -eu
node - <<'JS'
for (const status of [199, 200, 201, 202, 204, 299, 300, 401]) {
const response = new Response(null, { status });
console.log(`${status}: ok=${response.ok}`);
}
JS
printf '%s\n' '--- OpenRouter /key with dummy invalid key ---'
curl -sS -o /dev/null -w 'HTTP %{http_code}\n' \
-H 'Authorization: Bearer definitely-invalid-bigset-review-key' \
--max-time 15 \
'https://openrouter.ai/api/v1/key' || true
printf '%s\n' '--- OrcaRouter /models with dummy invalid key ---'
curl -sS -o /dev/null -w 'HTTP %{http_code}\n' \
-H 'Authorization: Bearer definitely-invalid-bigset-review-key' \
--max-time 15 \
'https://api.orcarouter.ai/v1/models' || trueRepository: tinyfish-io/bigset-oss Length of output: 1075 🏁 Script executed: #!/bin/bash
node - <<'JS'
for (const status of [200, 201, 202, 204, 299, 300, 401]) {
const response = new Response(null, { status });
console.log(`${status}: ok=${response.ok}`);
}
JS
printf '%s\n' '--- OpenRouter /key with dummy invalid key ---'
curl -sS -o /dev/null -w 'HTTP %{http_code}\n' \
-H 'Authorization: Bearer definitely-invalid-bigset-review-key' \
--max-time 15 \
'https://openrouter.ai/api/v1/key' || true
printf '%s\n' '--- OrcaRouter /models with dummy invalid key ---'
curl -sS -o /dev/null -w 'HTTP %{http_code}\n' \
-H 'Authorization: Bearer definitely-invalid-bigset-review-key' \
--max-time 15 \
'https://api.orcarouter.ai/v1/models' || trueRepository: tinyfish-io/bigset-oss Length of output: 531 Require HTTP 200 from the
🤖 Prompt for AI Agents |
||
|
|
||
| if (!response.ok) { | ||
| if (response.status === 401 || response.status === 403) { | ||
| throw new Error("OpenRouter rejected that API key."); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: tinyfish-io/bigset-oss
Length of output: 16085
🏁 Script executed:
Repository: tinyfish-io/bigset-oss
Length of output: 20138
🌐 Web query:
OpenRouter API /models output_modalities supported_parameters query parameters response pricing context_length OpenAI-compatible gateway💡 Result:
OpenRouter provides a unified, OpenAI-compatible API that aggregates access to hundreds of AI models through a single endpoint [1][2]. Model Discovery and Query Parameters The OpenRouter Models API allows you to programmatically discover and filter the model catalog via the /api/v1/models endpoint [3][1]. Key query parameters for this endpoint include: - output_modalities: Filters models by capabilities (e.g., text, image, audio, embeddings). Accepts a comma-separated list or "all"; defaults to "text" [4][3][5]. - supported_parameters: Filters models by the OpenAI-compatible parameters they support (e.g., tools, max_tokens, temperature, seed) [4][6][7]. - sort: Server-side sorting of models based on metrics like pricing, context length, latency, or popularity [3][7]. API Capabilities and Parameters OpenRouter's chat completions API is designed as a drop-in replacement for the OpenAI API [1][2]. It supports standard OpenAI parameters alongside additional features: - Core Parameters: Includes max_tokens, temperature, top_p, tools, tool_choice, and response_format [8][9][10]. - Advanced Parameters: Supports parameters such as seed, frequency_penalty, presence_penalty, logit_bias, top_k, min_p, and top_a [8][9][10]. - Plugins: OpenRouter supports plugins to extend model capabilities, such as web search (web), PDF parsing (file-parser), response healing (response-healing), and context compression [8][10]. - Provider Routing: Users can customize request routing using the provider object, which allows filtering or sorting based on price, throughput, or latency [11]. Pricing and Context - Context Length: The maximum context length (in tokens) is provided as metadata for each model in the /models response [4][7]. - Pricing: Pricing information is included in the model metadata [4][7]. Token counts and costs are calculated using the model's native tokenizer [8][9]. Historical usage, including token counts and costs for a specific generation, can be queried via the /api/v1/generation endpoint using the returned generation ID [8][9]. Gateway and Compatibility OpenRouter acts as an OpenAI-compatible gateway [1][2]. You can point the standard OpenAI SDK (or any other OpenAI-compatible library) directly at OpenRouter’s base URL to use its model catalog without significant code changes [1]. It also offers specific SDKs and an Agent SDK for more complex use cases like multi-turn conversations and tool execution [1].
Citations:
Limit
OPENROUTER_BASE_URLto gateways with BigSet’s model metadata contract.fetchModelsFromOpenRouter()expects/modelsentries withid,context_length, andpricing.prompt/completion. Missing metadata becomes0and appears in the model settings. Replaceany OpenAI-compatible gatewaywith supported gateways, or document this required response contract and query-parameter support.🤖 Prompt for AI Agents