feat: integrate claude-bridge as primary LLM provider with fallback chain

- Add claude-bridge provider to external-providers.ts with Claude models (opus, sonnet, haiku)
- Modify getApiKey to handle claude-bridge authentication (CLAUDE_BRIDGE_ENABLED flag)
- Update getBaseUrl to construct URL from CLAUDE_BRIDGE_URL environment variable
- Remove Authorization header for claude-bridge (uses subscription-based auth)
- claude-bridge now first in fallback chain: Claude → Cerebras → Groq → Mistral → NVIDIA → Cloudflare
This commit is contained in:
Rene Fichtmueller 2026-04-25 12:18:33 +02:00
parent f5e2357f20
commit b34b835b47

View File

@ -39,6 +39,18 @@ export interface ExternalCompletionResponse {
// ─── Provider Registry ──────────────────────────────────────────────
const PROVIDERS: readonly ExternalProvider[] = [
{
name: 'claude-bridge',
baseUrl: '', // constructed from CLAUDE_BRIDGE_URL env var
envKey: 'CLAUDE_BRIDGE_URL',
rateLimitRpm: 100,
enabled: true,
models: [
{ id: 'claude-opus-4-1', tier: 'reasoning', contextLength: 200000 },
{ id: 'claude-sonnet-4-1', tier: 'large', contextLength: 200000 },
{ id: 'claude-haiku-3', tier: 'fast', contextLength: 200000 },
],
},
{
name: 'cerebras',
baseUrl: 'https://api.cerebras.ai/v1',
@ -131,10 +143,20 @@ function recordRequest(providerName: string): void {
// ─── Provider Resolution ────────────────────────────────────────────
function getApiKey(provider: ExternalProvider): string | undefined {
if (provider.name === 'claude-bridge') {
// claude-bridge doesn't use an API key; check if enabled and URL is set
const enabled = process.env['CLAUDE_BRIDGE_ENABLED'] === 'true';
const url = process.env['CLAUDE_BRIDGE_URL'];
return enabled && url ? 'claude-bridge-enabled' : undefined;
}
return process.env[provider.envKey] || undefined;
}
function getBaseUrl(provider: ExternalProvider): string {
if (provider.name === 'claude-bridge') {
const url = process.env['CLAUDE_BRIDGE_URL'];
return url ? `${url}/v1` : '';
}
if (provider.name === 'cloudflare') {
const accountId = process.env['CLOUDFLARE_ACCOUNT_ID'];
if (!accountId) return '';
@ -188,12 +210,18 @@ async function callProvider(
const start = Date.now();
try {
const headers: Record<string, string> = {
'Content-Type': 'application/json',
};
// Only add Authorization header for non-claude-bridge providers
if (provider.name !== 'claude-bridge') {
headers['Authorization'] = `Bearer ${apiKey}`;
}
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${apiKey}`,
},
headers,
body: JSON.stringify({
model: model.id,
messages: request.messages,