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

@@ -0,0 +1,89 @@
import * as React from 'react'
import { useState } from 'react'
import { Box, Text } from '../ink.js'
import { saveFirepassApiKey } from '../utils/auth.js'
import { Spinner } from './Spinner.js'
import TextInput from './TextInput.js'
type FirepassLoginFlowProps = {
onDone: () => void
startingMessage?: string
}
export function FirepassLoginFlow({
onDone,
startingMessage,
}: FirepassLoginFlowProps): React.ReactNode {
const [isBusy, setIsBusy] = useState(false)
const [status, setStatus] = useState<string | null>(null)
const [inputValue, setInputValue] = useState('')
const [cursorOffset, setCursorOffset] = useState(0)
async function handleSubmit(value: string): Promise<void> {
const trimmed = value.trim()
if (!trimmed) {
return
}
setIsBusy(true)
setStatus(null)
try {
await saveFirepassApiKey(trimmed)
onDone()
} catch (error) {
setStatus(error instanceof Error ? error.message : String(error))
} finally {
setIsBusy(false)
}
}
if (isBusy) {
return (
<Box flexDirection="column" gap={1}>
<Box>
<Spinner />
<Text>Configuring FirePass login for Better-Clawd...</Text>
</Box>
<Text dimColor={true}>
FirePass uses your Fireworks API key with the Anthropic-compatible
endpoint at `https://api.fireworks.ai/inference`.
</Text>
</Box>
)
}
return (
<Box flexDirection="column" gap={1}>
<Text>
{startingMessage ??
'Better-Clawd can use FirePass with your Fireworks API key.'}
</Text>
<Text dimColor={true}>
FirePass provides subscription-based access to Kimi K2.5 Turbo with no
per-token charges. Get FirePass at{' '}
<Text color="cyan">https://app.fireworks.ai/fire-pass</Text>
</Text>
<Box>
<Text>Paste your Fireworks API key:</Text>
<TextInput
value={inputValue}
onChange={setInputValue}
onSubmit={handleSubmit}
onExit={() => {
setInputValue('')
setCursorOffset(0)
}}
cursorOffset={cursorOffset}
onChangeCursorOffset={setCursorOffset}
columns={72}
mask="*"
/>
</Box>
{status ? <Text color="error">{status}</Text> : null}
<Text dimColor={true}>
Press <Text bold={true}>Enter</Text> to save, or <Text bold={true}>Esc</Text>{' '}
to cancel.
</Text>
</Box>
)
}