Add FirePass provider support for Kimi K2.5 Turbo

- Add new 'firepass' provider type alongside anthropic, openai, openrouter
- FirePass uses Fireworks AI's endpoint for Kimi K2.5 Turbo model
- Subscription billing model ($7/week) with 256K context window
- Anthropic API compatible (uses Anthropic SDK with custom baseURL)

Changes:
- providers.ts: Add firepass detection and base URL handling
- auth.ts: Add FirePass API key management (FIREPASS_API_KEY or FIREWORKS_API_KEY)
- config.ts: Add firepassApiKey and firepass auth provider
- client.ts: Add firepass client creation with custom baseURL
- http.ts: Add firepass auth headers
- modelStrings.ts: Return Kimi K2.5 Turbo model ID for firepass
- model.ts: Add Kimi display name handling and default model logic
- modelOptions.ts: Simplified model picker for firepass (Kimi K2.5 Turbo only)
- status.tsx: Display FirePass in status bar
- login.tsx: Add FirePass option to provider selection
- FirepassLoginFlow.tsx: New component for FirePass login flow

Usage:
1. Run /login and select "FirePass"
2. Enter your Fireworks API key
3. Model picker shows Kimi K2.5 Turbo
This commit is contained in:
Jonathan Evans
2026-04-01 13:56:12 -07:00
Unverified
parent c9c145cf97
commit 061251984e
11 changed files with 389 additions and 8 deletions

View File

@@ -5,6 +5,7 @@ export type APIProvider =
| 'firstParty'
| 'openrouter'
| 'openai'
| 'firepass'
| 'bedrock'
| 'vertex'
| 'foundry'
@@ -20,10 +21,11 @@ function getStoredProviderPreference(): APIProvider | null {
require('../env.js') as typeof import('../env.js')
const raw = readFileSync(getGlobalClaudeFile(), 'utf8')
const config = JSON.parse(raw) as {
authProvider?: 'anthropic' | 'openrouter' | 'openai'
authProvider?: 'anthropic' | 'openrouter' | 'openai' | 'firepass'
openRouterApiKey?: string
openAiApiKey?: string
openAiAccessToken?: string
firepassApiKey?: string
}
switch (config.authProvider) {
@@ -33,6 +35,8 @@ function getStoredProviderPreference(): APIProvider | null {
return config.openAiApiKey || config.openAiAccessToken
? 'openai'
: null
case 'firepass':
return config.firepassApiKey ? 'firepass' : null
case 'anthropic':
return 'firstParty'
default:
@@ -57,6 +61,10 @@ function getExplicitProviderOverride(): APIProvider | null {
return 'openrouter'
case 'openai':
return 'openai'
case 'firepass':
case 'fire-pass':
case 'fire_pass':
return 'firepass'
case 'bedrock':
return 'bedrock'
case 'vertex':
@@ -98,6 +106,28 @@ export function isOpenAIConfigured(): boolean {
)
}
export function isFirepassBaseUrl(baseUrl?: string | null): boolean {
if (!baseUrl) {
return false
}
try {
const host = new URL(baseUrl).host
return host === 'api.fireworks.ai'
} catch {
return false
}
}
export function isFirepassConfigured(): boolean {
return (
getExplicitProviderOverride() === 'firepass' ||
Boolean(process.env.FIREPASS_API_KEY) ||
Boolean(process.env.FIREWORKS_API_KEY) ||
isFirepassBaseUrl(process.env.FIREPASS_BASE_URL) ||
isFirepassBaseUrl(process.env.ANTHROPIC_BASE_URL)
)
}
export function getOpenRouterBaseUrl(): string {
const configuredBaseUrl = process.env.OPENROUTER_BASE_URL
const fallbackBaseUrl = 'https://openrouter.ai/api'
@@ -129,6 +159,35 @@ export function getOpenAIBaseUrl(): string {
return process.env.OPENAI_BASE_URL ?? 'https://api.openai.com/v1'
}
/**
* Get the FirePass base URL for Anthropic-compatible API.
* FirePass uses Fireworks AI's inference endpoint with Anthropic compatibility.
* Default: https://api.fireworks.ai/inference (Anthropic SDK appends /v1/messages)
*/
export function getFirepassBaseUrl(): string {
const configuredBaseUrl = process.env.FIREPASS_BASE_URL
if (!configuredBaseUrl) {
return 'https://api.fireworks.ai/inference'
}
try {
const url = new URL(configuredBaseUrl)
// Normalize path for Anthropic SDK compatibility
// SDK appends /v1/messages, so base should be /inference not /inference/v1
if (url.host === 'api.fireworks.ai') {
const normalizedPath = url.pathname.replace(/\/+$/, '')
if (normalizedPath === '/inference/v1' || normalizedPath === '/v1') {
url.pathname = '/inference'
}
}
return url.toString().replace(/\/$/, '')
} catch {
return configuredBaseUrl
}
}
export function getAPIProvider(): APIProvider {
const explicitProvider = getExplicitProviderOverride()
if (explicitProvider) {
@@ -143,9 +202,11 @@ export function getAPIProvider(): APIProvider {
? 'foundry'
: isOpenAIConfigured()
? 'openai'
: isOpenRouterConfigured()
? 'openrouter'
: getStoredProviderPreference() ?? 'firstParty'
: isFirepassConfigured()
? 'firepass'
: isOpenRouterConfigured()
? 'openrouter'
: getStoredProviderPreference() ?? 'firstParty'
}
export function getAPIProviderForStatsig(): AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS {