Feat/bankr provider (#888)

* feat(provider): add Bankr LLM Gateway support

Add Bankr as an OpenAI-compatible provider preset with dedicated env vars:
- BNKR_API_KEY, BANKR_BASE_URL, BANKR_MODEL
- Uses X-API-Key header instead of Authorization Bearer
- Base URL: https://llm.bankr.bot/v1
- Default model: claude-opus-4.6

Changes:
- Add 'bankr' to VALID_PROVIDERS and provider flag handling
- Add buildBankrProfileEnv() with env key registration
- Add Bankr detection in startup screen and provider discovery
- Map Bankr env vars to OpenAI-compatible vars in shim
- Add Bankr preset to ProviderManager (alphabetical order)
- Update PRESET_ORDER test to include Bankr

Co-Authored-By: OpenClaude <openclaude@gitlawb.com>

* fixup(provider): address Bankr PR review feedback

1. Map BNKR_API_KEY → OPENAI_API_KEY in providerFlag.ts so
   --provider bankr works with BNKR_API_KEY in non-interactive startup.

2. Remove unconditional BANKR_MODEL read from model.ts; it maps to
   OPENAI_MODEL via providerFlag.ts and openaiShim.ts, preventing
   cross-provider leakage.

3. Use X-API-Key for Bankr model discovery in openaiModelDiscovery.ts
   and providerDiscovery.ts, matching chat request auth.

Co-Authored-By: OpenClaude <openclaude@gitlawb.com>

---------

Co-authored-by: OpenClaude <openclaude@gitlawb.com>
This commit is contained in:
Kevin Codex
2026-04-24 23:03:45 +08:00
committed by GitHub
parent 5a21d05741
commit 64b1014b9a
10 changed files with 130 additions and 6 deletions

View File

@@ -70,6 +70,9 @@ const PROFILE_ENV_KEYS = [
'MISTRAL_BASE_URL',
'MISTRAL_API_KEY',
'MISTRAL_MODEL',
'BANKR_BASE_URL',
'BNKR_API_KEY',
'BANKR_MODEL',
] as const
const SECRET_ENV_KEYS = [
@@ -80,6 +83,7 @@ const SECRET_ENV_KEYS = [
'NVIDIA_API_KEY',
'MINIMAX_API_KEY',
'MISTRAL_API_KEY',
'BNKR_API_KEY',
] as const
export type ProviderProfile = 'openai' | 'ollama' | 'codex' | 'gemini' | 'atomic-chat' | 'nvidia-nim' | 'minimax' | 'mistral'
@@ -105,6 +109,9 @@ export type ProfileEnv = {
MISTRAL_BASE_URL?: string
MISTRAL_API_KEY?: string
MISTRAL_MODEL?: string
BANKR_BASE_URL?: string
BNKR_API_KEY?: string
BANKR_MODEL?: string
}
export type ProfileFile = {
@@ -121,7 +128,8 @@ type SecretValueSource = Partial<
| 'GOOGLE_API_KEY'
| 'NVIDIA_API_KEY'
| 'MINIMAX_API_KEY'
| 'MISTRAL_API_KEY',
| 'MISTRAL_API_KEY'
| 'BNKR_API_KEY',
string | undefined
>
>
@@ -395,6 +403,42 @@ export function buildMistralProfileEnv(options: {
return env
}
export function buildBankrProfileEnv(options: {
model?: string | null
baseUrl?: string | null
apiKey?: string | null
processEnv?: NodeJS.ProcessEnv
}): ProfileEnv | null {
const processEnv = options.processEnv ?? process.env
const key = sanitizeApiKey(options.apiKey ?? processEnv.BNKR_API_KEY)
if (!key) {
return null
}
const env: ProfileEnv = {
BNKR_API_KEY: key,
BANKR_MODEL:
sanitizeProviderConfigValue(options.model, { BNKR_API_KEY: key }) ||
sanitizeProviderConfigValue(
processEnv.BANKR_MODEL,
{ BNKR_API_KEY: key },
) ||
'claude-opus-4.6',
}
const baseUrl =
sanitizeProviderConfigValue(options.baseUrl, { BNKR_API_KEY: key }) ||
sanitizeProviderConfigValue(
processEnv.BANKR_BASE_URL,
{ BNKR_API_KEY: key },
)
if (baseUrl) {
env.BANKR_BASE_URL = baseUrl
}
return env
}
export function buildCodexOAuthProfileEnv(
tokens: {
accessToken: string