feat(gateway): add Concentrate AI provider with dynamic model discovery (#2140)

* feat(gateway): add Concentrate AI provider with dynamic model discovery

* fix(concentrate): prompt for Concentrate API key in /provider instead of pre-filling OPENAI_API_KEY

* docs(concentrate): remove standalone setup guide to match other gateways

* fix(concentrate): dedicated-credential-only routing, env-only identity, and credential isolation

- Make Concentrate dedicatedCredentialsOnly so ambient OPENAI_API_KEY is never
  forwarded. Only CONCENTRATE_API_KEY authenticates the route.
- Resolve Concentrate env-only route identity from CONCENTRATE_API_KEY,
  CONCENTRATE_BASE_URL, CONCENTRATE_MODEL, or a Concentrate-shaped
  OPENAI_BASE_URL.
- Mirror the dedicated credential into OPENAI_API_KEY only after the route
  identity is established and only for the canonical /v1 inference endpoint.
- Add Concentrate support to --provider concentrate, saved profiles, startup
  env rebuild, and .env allowlist.
- Add regression tests for env-only, flag, saved-profile, and client routing.
- Fix adjacent ApiSmart keyless profile leaking string 'undefined' into
  OPENAI_API_KEY and extend the first providerProfiles test timeout for the
  now-slower fresh module import.

* fix(concentrate): protect credentials on noncanonical urls

* fix(concentrate): drop legacy keys on retargeted profiles

* fix(concentrate): remove legacy generic keys on proxies

* fix(concentrate): reject noncanonical credential routes

* fix(concentrate): validate env-only credentials

* fix(concentrate): align env-only route validation

* fix(concentrate): clear headers before client setup

* test(validation): isolate Concentrate model env

* fix(concentrate): honor provider precedence and model defaults

* test(concentrate): cover model resolution precedence

* fix(concentrate): preserve legacy model fallback

* fix(concentrate): normalize early model selection

* fix(concentrate): validate and select rejected models safely

* fix(concentrate): reset stale route state

* fix(concentrate): preserve proxy profile capabilities
This commit is contained in:
JATMN
2026-08-19 09:58:18 +08:00
committed by GitHub
parent 108a413493
commit 084bc53463
26 changed files with 1956 additions and 107 deletions
+1
View File
@@ -141,6 +141,7 @@ const PRESET_ORDER = [
'Bankr',
'ClinePass',
'Cloudflare Workers AI',
'Concentrate',
'DeepSeek',
'Codex OAuth',
'xAI OAuth (Grok)',
@@ -0,0 +1,79 @@
import { describe, expect, test } from 'bun:test'
import concentrate from './concentrate.js'
const mapModel = concentrate.catalog?.discovery?.mapModel
describe('concentrate gateway', () => {
test('uses dynamic discovery and supports fallback auth', () => {
expect(concentrate.id).toBe('concentrate')
expect(concentrate.label).toBe('Concentrate')
expect(concentrate.category).toBe('aggregating')
expect(concentrate.defaultBaseUrl).toBe('https://api.concentrate.ai/v1')
expect(concentrate.defaultModel).toBe('deepseek-v4-flash')
expect(concentrate.supportsModelRouting).toBe(true)
expect(concentrate.setup.requiresAuth).toBe(true)
expect(concentrate.setup.authMode).toBe('api-key')
expect(concentrate.setup.credentialEnvVars).toEqual(['CONCENTRATE_API_KEY'])
expect(concentrate.setup.dedicatedCredentialsOnly).toBeUndefined()
expect(concentrate.catalog?.source).toBe('dynamic')
expect(concentrate.catalog?.discovery?.kind).toBe('openai-compatible')
expect(concentrate.catalog?.discovery?.requiresAuth).toBe(false)
expect(concentrate.validation?.kind).toBe('credential-env')
expect(
(concentrate.validation as { credentialEnvVars: string[] }).credentialEnvVars,
).toEqual([
'CONCENTRATE_API_KEY',
'OPENAI_API_KEYS',
'OPENAI_API_KEY',
])
expect(mapModel).toBeDefined()
})
test('mapModel keeps chat models and drops non-chat ids', () => {
if (!mapModel) throw new Error('mapModel missing')
expect(
mapModel({
id: 'deepseek-v4-flash',
display_name: 'DeepSeek V4 Flash',
owned_by: 'deepseek',
max_input_tokens: 1_048_576,
max_tokens: 393_216,
}),
).toEqual({
id: 'deepseek-v4-flash',
apiName: 'deepseek-v4-flash',
label: 'DeepSeek V4 Flash',
contextWindow: 1_048_576,
maxOutputTokens: 393_216,
})
expect(
mapModel({
id: 'claude-sonnet-5',
display_name: 'Claude Sonnet 5',
owned_by: 'anthropic',
max_input_tokens: 200_000,
max_tokens: 64_000,
}),
).toEqual({
id: 'claude-sonnet-5',
apiName: 'claude-sonnet-5',
label: 'Claude Sonnet 5',
contextWindow: 200_000,
maxOutputTokens: 64_000,
})
expect(mapModel({ id: 'redact-v1' })).toBeNull()
expect(mapModel({ id: 'gpt-oss-safeguard-120b' })).toBeNull()
expect(mapModel({ id: 'text-embedding-3-small' })).toBeNull()
expect(mapModel({ id: 'whisper-1' })).toBeNull()
expect(mapModel({})).toBeNull()
expect(mapModel(null)).toBeNull()
})
})
+111
View File
@@ -0,0 +1,111 @@
import { defineGateway } from '../define.js'
const NON_CHAT_MODEL_PATTERN =
/redact|safeguard|embed|embedding|whisper|tts|dall-e|rerank|moderation|image-generation|video-generation|audio-generation/i
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null
}
function getTrimmedString(
record: Record<string, unknown>,
key: string,
): string | undefined {
const value = record[key]
return typeof value === 'string' ? value.trim() : undefined
}
function getPositiveInteger(value: unknown): number | undefined {
if (
typeof value === 'number' &&
Number.isFinite(value) &&
Number.isInteger(value) &&
value > 0
) {
return value
}
return undefined
}
function mapConcentrateModel(raw: unknown) {
if (!isRecord(raw)) {
return null
}
const id = getTrimmedString(raw, 'id')
if (!id || NON_CHAT_MODEL_PATTERN.test(id)) {
return null
}
const displayName = getTrimmedString(raw, 'display_name')
const label = displayName || id
const contextWindow = getPositiveInteger(raw.max_input_tokens)
const maxOutputTokens = getPositiveInteger(raw.max_tokens)
return {
id,
apiName: id,
label,
...(contextWindow !== undefined ? { contextWindow } : {}),
...(maxOutputTokens !== undefined ? { maxOutputTokens } : {}),
}
}
export default defineGateway({
id: 'concentrate',
label: 'Concentrate',
category: 'aggregating',
defaultBaseUrl: 'https://api.concentrate.ai/v1',
defaultModel: 'deepseek-v4-flash',
supportsModelRouting: true,
setup: {
requiresAuth: true,
authMode: 'api-key',
credentialEnvVars: ['CONCENTRATE_API_KEY'],
},
startup: {
probeReadiness: 'openai-compatible-models',
},
transportConfig: {
kind: 'openai-compatible',
openaiShim: {
supportsApiFormatSelection: false,
supportsAuthHeaders: false,
maxTokensField: 'max_tokens',
},
},
preset: {
id: 'concentrate',
description: 'Concentrate AI — 150+ models via OpenAI-compatible API',
vendorId: 'openai',
apiKeyEnvVars: ['CONCENTRATE_API_KEY'],
baseUrlEnvVars: ['CONCENTRATE_BASE_URL'],
modelEnvVars: ['CONCENTRATE_MODEL', 'OPENAI_MODEL'],
},
validation: {
kind: 'credential-env',
routing: {
matchDefaultBaseUrl: true,
matchBaseUrlHosts: ['api.concentrate.ai'],
},
credentialEnvVars: [
'CONCENTRATE_API_KEY',
'OPENAI_API_KEYS',
'OPENAI_API_KEY',
],
missingCredentialMessage:
'Concentrate auth is required. Set CONCENTRATE_API_KEY or OPENAI_API_KEY.',
},
catalog: {
source: 'dynamic',
discovery: {
kind: 'openai-compatible',
requiresAuth: false,
mapModel: mapConcentrateModel,
},
discoveryCacheTtl: '1d',
discoveryRefreshMode: 'startup',
allowManualRefresh: true,
},
usage: { supported: false },
})
@@ -27,6 +27,7 @@ import gatewayAzureOpenai from '../gateways/azure-openai.js'
import gatewayBedrock from '../gateways/bedrock.js'
import gatewayClinepass from '../gateways/clinepass.js'
import gatewayCloudflare from '../gateways/cloudflare.js'
import gatewayConcentrate from '../gateways/concentrate.js'
import gatewayCustom from '../gateways/custom.js'
import gatewayDashscopeCn from '../gateways/dashscope-cn.js'
import gatewayDashscopeIntl from '../gateways/dashscope-intl.js'
@@ -90,7 +91,7 @@ import modelXai from '../models/xai.js'
import modelXiaomiMimo from '../models/xiaomi-mimo.js'
export const VENDOR_DESCRIPTORS = [vendorAnthropic, vendorBankr, vendorDeepseek, vendorFireworks, vendorGemini, vendorLongcat, vendorMinimax, vendorMoonshot, vendorNearai, vendorOpenai, vendorVenice, vendorXai, vendorXiaomiMimo, vendorZai] as const satisfies readonly VendorDescriptor[]
export const GATEWAY_DESCRIPTORS = [gatewayAimlapi, gatewayApismart, gatewayAtlasCloud, gatewayAtomicChat, gatewayAzureOpenai, gatewayBedrock, gatewayClinepass, gatewayCloudflare, gatewayCustom, gatewayDashscopeCn, gatewayDashscopeIntl, gatewayGithubEnterprise, gatewayGithub, gatewayGitlawbOpengateway, gatewayGroq, gatewayHicap, gatewayKimiCode, gatewayLmstudio, gatewayMistral, gatewayNvidiaNim, gatewayOllama, gatewayOpencodeGo, gatewayOpencode, gatewayOpenrouter, gatewayTogether, gatewayVertex, gatewayXiaomiMimoToken] as const satisfies readonly GatewayDescriptor[]
export const GATEWAY_DESCRIPTORS = [gatewayAimlapi, gatewayApismart, gatewayAtlasCloud, gatewayAtomicChat, gatewayAzureOpenai, gatewayBedrock, gatewayClinepass, gatewayCloudflare, gatewayConcentrate, gatewayCustom, gatewayDashscopeCn, gatewayDashscopeIntl, gatewayGithubEnterprise, gatewayGithub, gatewayGitlawbOpengateway, gatewayGroq, gatewayHicap, gatewayKimiCode, gatewayLmstudio, gatewayMistral, gatewayNvidiaNim, gatewayOllama, gatewayOpencodeGo, gatewayOpencode, gatewayOpenrouter, gatewayTogether, gatewayVertex, gatewayXiaomiMimoToken] as const satisfies readonly GatewayDescriptor[]
export const ANTHROPIC_PROXY_DESCRIPTORS = [anthropicproxyCustom] as const satisfies readonly AnthropicProxyDescriptor[]
export const BRAND_DESCRIPTORS = [brandClaude, brandDeepseek, brandFireworks, brandGemini, brandGlm, brandGpt, brandKimi, brandLing, brandLlama, brandLongcat, brandMacaron, brandMinimax, brandMistral, brandNearai, brandNemotron, brandOpenaiCompatibleAlias, brandQwen, brandTencent, brandXai, brandXiaomiMimo] as const satisfies readonly BrandDescriptor[]
export const MODEL_DESCRIPTOR_GROUPS = [modelClaude, modelDeepseek, modelFireworksMerged, modelGemini, modelGlm, modelGpt, modelKimi, modelLing, modelLlama, modelLongcat, modelMacaron, modelMinimax, modelMistral, modelNearai, modelNemotron, modelOpenaiCompatibleAlias, modelOpencode, modelQwen, modelTencent, modelXai, modelXiaomiMimo] as const satisfies readonly (readonly ModelDescriptor[])[]
@@ -176,6 +176,24 @@ export const PROVIDER_PRESET_MANIFEST = [
"OPENAI_MODEL"
]
},
{
"preset": "concentrate",
"routeKind": "gateway",
"routeId": "concentrate",
"vendorId": "openai",
"gatewayId": "concentrate",
"description": "Concentrate AI — 150+ models via OpenAI-compatible API",
"apiKeyEnvVars": [
"CONCENTRATE_API_KEY"
],
"baseUrlEnvVars": [
"CONCENTRATE_BASE_URL"
],
"modelEnvVars": [
"CONCENTRATE_MODEL",
"OPENAI_MODEL"
]
},
{
"preset": "deepseek",
"routeKind": "vendor",
@@ -548,6 +566,7 @@ export const ORDERED_PROVIDER_PRESETS = [
"bankr",
"clinepass",
"cloudflare",
"concentrate",
"deepseek",
"fireworks",
"gemini",
+1
View File
@@ -88,6 +88,7 @@ describe('loaded registry validation', () => {
test('gateway defaultModel values are present unless provided outside curated catalog metadata', () => {
const routesWithExternalDefaultModelSources = new Set([
'atomic-chat',
'concentrate',
'custom',
'lmstudio',
'ollama',
+134
View File
@@ -9,6 +9,7 @@ import {
isApismartBaseUrl,
isCanonicalApismartInferenceBaseUrl,
isCloudflareBaseUrl,
isConcentrateBaseUrl,
isLongcatBaseUrl,
resolveActiveRouteIdFromEnv,
resolveRouteCredentialValue,
@@ -1009,3 +1010,136 @@ test('getRouteDefaultModel skips hidden and expired catalog entries in the fallb
}
}
})
test('isConcentrateBaseUrl matches the Concentrate API host', () => {
expect(isConcentrateBaseUrl('https://api.concentrate.ai/v1')).toBe(true)
expect(isConcentrateBaseUrl('https://api.concentrate.ai/v1/chat/completions')).toBe(true)
expect(isConcentrateBaseUrl('http://api.concentrate.ai/v1')).toBe(false)
expect(isConcentrateBaseUrl('https://api.concentrate.ai:8443/v1')).toBe(false)
expect(isConcentrateBaseUrl('https://api.concentrate.ai.evil.test/v1')).toBe(false)
expect(isConcentrateBaseUrl(undefined)).toBe(false)
})
test('resolveActiveRouteIdFromEnv treats Concentrate credential-only env as Concentrate', () => {
expect(
resolveActiveRouteIdFromEnv({
CONCENTRATE_API_KEY: 'concentrate-key',
}),
).toBe('concentrate')
})
test('resolveActiveRouteIdFromEnv uses CONCENTRATE_BASE_URL with a dedicated credential', () => {
expect(
resolveActiveRouteIdFromEnv({
CONCENTRATE_API_KEY: 'concentrate-key',
CONCENTRATE_BASE_URL: 'https://api.concentrate.ai/v1',
}),
).toBe('concentrate')
})
test('resolveActiveRouteIdFromEnv uses CONCENTRATE_MODEL with a dedicated credential', () => {
expect(
resolveActiveRouteIdFromEnv({
CONCENTRATE_API_KEY: 'concentrate-key',
CONCENTRATE_MODEL: 'claude-sonnet-5',
}),
).toBe('concentrate')
})
test('resolveActiveRouteIdFromEnv ignores placeholder Concentrate credentials', () => {
expect(
resolveActiveRouteIdFromEnv({
CONCENTRATE_API_KEY: 'SUA_CHAVE',
}),
).not.toBe('concentrate')
expect(
resolveActiveRouteIdFromEnv({
CONCENTRATE_API_KEY: 'null',
}),
).not.toBe('concentrate')
expect(
resolveActiveRouteIdFromEnv({
CONCENTRATE_API_KEY: 'undefined',
}),
).not.toBe('concentrate')
})
test('resolveActiveRouteIdFromEnv prefers Concentrate dedicated key over ambient OpenAI credentials', () => {
expect(
resolveActiveRouteIdFromEnv({
CONCENTRATE_API_KEY: 'concentrate-key',
OPENAI_API_KEY: 'ambient-openai-key',
OPENAI_API_KEYS: 'ambient-openai-key-a,ambient-openai-key-b',
}),
).toBe('concentrate')
})
test('resolveActiveRouteIdFromEnv does not infer Concentrate with a conflicting OpenAI base URL', () => {
expect(
resolveActiveRouteIdFromEnv({
CONCENTRATE_API_KEY: 'concentrate-key',
OPENAI_BASE_URL: 'https://api.openai.com/v1',
}),
).toBe('anthropic')
})
test('resolveActiveRouteIdFromEnv does not infer Concentrate from a same-host noncanonical base URL', () => {
expect(
resolveActiveRouteIdFromEnv({
CLAUDE_CODE_USE_OPENAI: '1',
OPENAI_BASE_URL: 'https://api.concentrate.ai/staging/v1',
}),
).toBe('custom')
})
test('resolveActiveRouteIdFromEnv keeps an explicit non-OpenAI provider over Concentrate key-only setup', () => {
expect(
resolveActiveRouteIdFromEnv({
CONCENTRATE_API_KEY: 'concentrate-key',
CLAUDE_CODE_USE_GEMINI: '1',
}),
).toBe('gemini')
})
test('resolveActiveRouteIdFromEnv honors an explicit OpenAI opt-out over Concentrate', () => {
expect(resolveActiveRouteIdFromEnv({ CLAUDE_CODE_USE_OPENAI: '0', CONCENTRATE_API_KEY: 'concentrate-key' })).not.toBe('concentrate')
})
test('resolveActiveRouteIdFromEnv refines generic OpenAI profile by Concentrate base URL', () => {
expect(
resolveActiveRouteIdFromEnv({
CLAUDE_CODE_USE_OPENAI: '1',
OPENAI_BASE_URL: 'https://api.concentrate.ai/v1',
}),
).toBe('concentrate')
})
test('getRouteCredentialEnvVars supports documented generic OpenAI Concentrate setup', () => {
expect(getRouteCredentialEnvVars('concentrate')).toEqual([
'CONCENTRATE_API_KEY',
'OPENAI_API_KEYS',
'OPENAI_API_KEY',
])
expect(
getRouteCredentialValue('concentrate', {
OPENAI_API_KEY: 'generic-openai-key',
}),
).toBe('generic-openai-key')
expect(
getRouteCredentialValue('concentrate', {
OPENAI_API_KEY: 'generic-openai-key',
CONCENTRATE_API_KEY: 'concentrate-key',
}),
).toBe('concentrate-key')
})
test('resolveActiveRouteIdFromEnv does not let a stale Concentrate model override generic OpenAI', () => {
expect(
resolveActiveRouteIdFromEnv({
CLAUDE_CODE_USE_OPENAI: '1',
OPENAI_BASE_URL: 'https://api.openai.com/v1',
OPENAI_API_KEY: 'generic-openai-key',
CONCENTRATE_MODEL: 'deepseek-v4-flash-0731',
}),
).toBe('openai')
})
+99 -2
View File
@@ -230,7 +230,8 @@ function hasUsableEnvCredentialValue(
envVar === 'OPENAI_API_KEYS' ||
envVar === 'OPENAI_API_KEY' ||
envVar === 'AIMLAPI_API_KEY' ||
envVar === 'APISMART_API_KEY'
envVar === 'APISMART_API_KEY' ||
envVar === 'CONCENTRATE_API_KEY'
) {
return hasUsableOpenAICredential(value)
}
@@ -418,6 +419,70 @@ export function isClinePassBaseUrl(value: string | undefined): boolean {
}
}
export function isConcentrateBaseUrl(value: string | undefined): boolean {
const trimmed = value?.trim()
if (!trimmed) {
return false
}
try {
const url = new URL(trimmed)
return (
url.protocol === 'https:' &&
!url.port &&
!url.search &&
!url.hash &&
url.hostname.toLowerCase() === 'api.concentrate.ai'
)
} catch {
return false
}
}
const CONCENTRATE_CANONICAL_INFERENCE_BASE_URL = 'https://api.concentrate.ai/v1'
export function isCanonicalConcentrateInferenceBaseUrl(
value: string | undefined,
): boolean {
const trimmed = value?.trim()
if (!trimmed) {
return false
}
try {
const canonical = new URL(CONCENTRATE_CANONICAL_INFERENCE_BASE_URL)
const candidate = new URL(trimmed)
const normalizePath = (pathname: string): string =>
pathname.replace(/\/+$/, '') || '/'
return (
candidate.protocol === 'https:' &&
!candidate.port &&
!candidate.search &&
!candidate.hash &&
candidate.hostname.toLowerCase() === canonical.hostname.toLowerCase() &&
normalizePath(candidate.pathname) === normalizePath(canonical.pathname)
)
} catch {
return false
}
}
export function getConcentrateBaseUrlOverride(
processEnv: NodeJS.ProcessEnv = process.env,
): string | undefined {
const openAIBaseUrl = processEnv.OPENAI_BASE_URL?.trim()
if (isConcentrateBaseUrl(openAIBaseUrl)) {
return openAIBaseUrl
}
const openAIApiBase = processEnv.OPENAI_API_BASE?.trim()
if (isConcentrateBaseUrl(openAIApiBase)) {
return openAIApiBase
}
return undefined
}
/**
* Host-scoped ApiSmart route match. Used for env-only conflict detection and
* base-URL route identity (including `/v1/chat/completions` path suffixes that
@@ -886,6 +951,22 @@ export function hasApismartEnvOnlyProviderIntent(
)
}
export function hasConcentrateEnvOnlyProviderIntent(
processEnv: NodeJS.ProcessEnv = process.env,
): boolean {
// The dedicated credential explicitly selects Concentrate. Base/model
// overrides alone are configuration details, not route identity: treating
// them as identity would let a stale optional setting override a valid
// generic OpenAI configuration.
return (
hasUsableOpenAICredential(processEnv.CONCENTRATE_API_KEY) &&
!hasConflictingOpenAIBaseUrlForRoute(processEnv, isConcentrateBaseUrl) &&
!(processEnv.CLAUDE_CODE_USE_OPENAI !== undefined &&
!isEnvTruthy(processEnv.CLAUDE_CODE_USE_OPENAI)) &&
hasNoExplicitNonOpenAIProvider(processEnv)
)
}
export function resolveEnvOnlyProviderRouteId(
processEnv: NodeJS.ProcessEnv = process.env,
):
@@ -899,6 +980,7 @@ export function resolveEnvOnlyProviderRouteId(
| 'longcat'
| 'clinepass'
| 'apismart'
| 'concentrate'
| null {
if (
hasMiniMaxRouteIntent(processEnv) &&
@@ -947,6 +1029,10 @@ export function resolveEnvOnlyProviderRouteId(
return 'apismart'
}
if (hasConcentrateEnvOnlyProviderIntent(processEnv)) {
return 'concentrate'
}
return null
}
@@ -1022,6 +1108,15 @@ export function resolveRouteCredentialValue(
) {
return undefined
}
// Concentrate is the same: route identity is host-scoped, but the dedicated
// credential is only valid for the documented /v1 inference endpoint.
if (
routeId === 'concentrate' &&
options?.baseUrl !== undefined &&
!isCanonicalConcentrateInferenceBaseUrl(options.baseUrl)
) {
return undefined
}
return getRouteCredentialValue(routeId, processEnv)
}
@@ -1144,7 +1239,9 @@ export function resolveRouteIdFromBaseUrl(
if (
(route.id === 'cloudflare' && !isCloudflareBaseUrl(baseUrl)) ||
(route.id === 'longcat' && !isLongcatBaseUrl(baseUrl)) ||
(route.id === 'apismart' && !isApismartBaseUrl(baseUrl))
(route.id === 'apismart' && !isApismartBaseUrl(baseUrl)) ||
(route.id === 'concentrate' &&
!isCanonicalConcentrateInferenceBaseUrl(baseUrl))
) {
continue
}
+122
View File
@@ -69,6 +69,9 @@ const originalEnv = {
LONGCAT_API_KEY: process.env.LONGCAT_API_KEY,
AIMLAPI_API_KEY: process.env.AIMLAPI_API_KEY,
APISMART_API_KEY: process.env.APISMART_API_KEY,
CONCENTRATE_API_KEY: process.env.CONCENTRATE_API_KEY,
CONCENTRATE_BASE_URL: process.env.CONCENTRATE_BASE_URL,
CONCENTRATE_MODEL: process.env.CONCENTRATE_MODEL,
NVIDIA_NIM: process.env.NVIDIA_NIM,
NVIDIA_API_KEY: process.env.NVIDIA_API_KEY,
ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
@@ -165,6 +168,9 @@ beforeEach(async () => {
delete process.env.LONGCAT_API_KEY
delete process.env.AIMLAPI_API_KEY
delete process.env.APISMART_API_KEY
delete process.env.CONCENTRATE_API_KEY
delete process.env.CONCENTRATE_BASE_URL
delete process.env.CONCENTRATE_MODEL
delete process.env.OPENAI_AUTH_HEADER
delete process.env.OPENAI_AUTH_SCHEME
delete process.env.OPENAI_AUTH_HEADER_VALUE
@@ -215,6 +221,9 @@ afterEach(() => {
restoreEnv('LONGCAT_API_KEY', originalEnv.LONGCAT_API_KEY)
restoreEnv('AIMLAPI_API_KEY', originalEnv.AIMLAPI_API_KEY)
restoreEnv('APISMART_API_KEY', originalEnv.APISMART_API_KEY)
restoreEnv('CONCENTRATE_API_KEY', originalEnv.CONCENTRATE_API_KEY)
restoreEnv('CONCENTRATE_BASE_URL', originalEnv.CONCENTRATE_BASE_URL)
restoreEnv('CONCENTRATE_MODEL', originalEnv.CONCENTRATE_MODEL)
restoreEnv('NVIDIA_NIM', originalEnv.NVIDIA_NIM)
restoreEnv('NVIDIA_API_KEY', originalEnv.NVIDIA_API_KEY)
restoreEnv('ANTHROPIC_API_KEY', originalEnv.ANTHROPIC_API_KEY)
@@ -771,6 +780,119 @@ test('env-only ApiSmart setup withholds its key from a noncanonical same-host UR
expect(process.env.OPENAI_API_KEY).toBeUndefined()
})
test('routes env-only Concentrate requests through the OpenAI-compatible shim', async () => {
let capturedUrl: string | undefined
let capturedHeaders: Headers | undefined
let capturedBody: Record<string, unknown> | undefined
delete process.env.CLAUDE_CODE_USE_GEMINI
delete process.env.GEMINI_API_KEY
delete process.env.GEMINI_MODEL
delete process.env.GEMINI_BASE_URL
delete process.env.GEMINI_AUTH_MODE
process.env.CONCENTRATE_API_KEY = 'concentrate-test-key'
process.env.CONCENTRATE_BASE_URL = 'https://api.concentrate.ai/v1'
process.env.CONCENTRATE_MODEL = 'claude-sonnet-5'
process.env.ANTHROPIC_CUSTOM_HEADERS = 'X-Proxy-Auth: ambient-proxy-secret'
globalThis.fetch = (async (input, init) => {
capturedUrl =
typeof input === 'string'
? input
: input instanceof URL
? input.toString()
: input.url
capturedHeaders = new Headers(init?.headers)
capturedBody = JSON.parse(String(init?.body)) as Record<string, unknown>
return new Response(
JSON.stringify({
id: 'chatcmpl-concentrate',
model: 'claude-sonnet-5',
choices: [
{
message: {
role: 'assistant',
content: 'concentrate ok',
},
finish_reason: 'stop',
},
],
usage: {
prompt_tokens: 8,
completion_tokens: 3,
total_tokens: 11,
},
}),
{
headers: {
'Content-Type': 'application/json',
},
},
)
}) as FetchType
const client = (await getAnthropicClient({
maxRetries: 0,
model: 'claude-sonnet-5',
})) as unknown as ShimClient
const response = await client.beta.messages.create({
model: 'claude-sonnet-5',
system: 'test system',
messages: [{ role: 'user', content: 'hello' }],
max_tokens: 64,
stream: false,
})
expect(capturedUrl).toBe('https://api.concentrate.ai/v1/chat/completions')
expect(capturedHeaders?.get('authorization')).toBe('Bearer concentrate-test-key')
expect(capturedHeaders?.get('x-proxy-auth')).toBeNull()
expect(capturedBody?.model).toBe('claude-sonnet-5')
expect(process.env.OPENAI_BASE_URL).toBe('https://api.concentrate.ai/v1')
expect(process.env.OPENAI_API_KEY).toBe('concentrate-test-key')
expect(response).toMatchObject({
role: 'assistant',
model: 'claude-sonnet-5',
})
})
test('env-only Concentrate setup withholds its key from a noncanonical same-host URL', async () => {
delete process.env.CLAUDE_CODE_USE_GEMINI
delete process.env.GEMINI_API_KEY
delete process.env.GEMINI_MODEL
delete process.env.GEMINI_BASE_URL
delete process.env.GEMINI_AUTH_MODE
process.env.CONCENTRATE_API_KEY = 'concentrate-test-key'
process.env.OPENAI_BASE_URL = 'https://api.concentrate.ai/v1/models'
await getAnthropicClient({ maxRetries: 0, model: 'claude-sonnet-5' })
expect(process.env.CLAUDE_CODE_USE_OPENAI).toBe('1')
expect(process.env.OPENAI_BASE_URL).toBe(
'https://api.concentrate.ai/v1/models',
)
expect(process.env.OPENAI_API_KEY).toBeUndefined()
})
test('generic OpenAI configuration for the canonical Concentrate endpoint retains its key', async () => {
delete process.env.CLAUDE_CODE_USE_GEMINI
delete process.env.GEMINI_API_KEY
delete process.env.GEMINI_MODEL
delete process.env.GEMINI_BASE_URL
delete process.env.GEMINI_AUTH_MODE
process.env.OPENAI_API_KEY = 'generic-openai-key'
process.env.OPENAI_BASE_URL = 'https://api.concentrate.ai/v1'
process.env.OPENAI_MODEL = 'claude-sonnet-5'
await getAnthropicClient({ maxRetries: 0, model: 'claude-sonnet-5' })
expect(process.env.CLAUDE_CODE_USE_OPENAI).toBeUndefined()
expect(process.env.OPENAI_BASE_URL).toBe('https://api.concentrate.ai/v1')
expect(process.env.OPENAI_MODEL).toBe('claude-sonnet-5')
expect(process.env.OPENAI_API_KEY).toBe('generic-openai-key')
})
test('routes env-only AI/ML API requests through the OpenAI-compatible shim despite an ambient OpenAI key', async () => {
let capturedUrl: string | undefined
let capturedHeaders: Headers | undefined
+74 -44
View File
@@ -44,6 +44,7 @@ import {
getMiniMaxBaseUrlOverride,
getNearaiBaseUrlOverride,
isCanonicalApismartInferenceBaseUrl,
isCanonicalConcentrateInferenceBaseUrl,
getRouteDefaultBaseUrl,
getRouteDefaultModel,
getXaiBaseUrlOverride,
@@ -411,6 +412,43 @@ function applyApismartEnvOnlyDefaults(): void {
delete process.env.ANTHROPIC_CUSTOM_HEADERS
}
function applyConcentrateEnvOnlyDefaults(): void {
const baseUrlOverride =
usableProviderConfigEnvValue(process.env.CONCENTRATE_BASE_URL) ||
usableProviderConfigEnvValue(process.env.OPENAI_BASE_URL) ||
usableProviderConfigEnvValue(process.env.OPENAI_API_BASE) ||
undefined
const modelOverride =
usableProviderConfigEnvValue(process.env.CONCENTRATE_MODEL) ||
usableProviderConfigEnvValue(process.env.OPENAI_MODEL) ||
undefined
const apiKey = process.env.CONCENTRATE_API_KEY
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.OPENAI_BASE_URL =
baseUrlOverride ?? getRouteDefaultBaseUrl('concentrate')
process.env.OPENAI_MODEL = modelOverride ?? getRouteDefaultModel('concentrate')
// A dedicated key explicitly selects Concentrate. Mirror it into
// OPENAI_API_KEY for the shared transport and avoid forwarding a stale
// generic credential. Generic OpenAI credentials remain supported when the
// user explicitly configures the canonical Concentrate base URL without the
// dedicated selection key.
if (
hasUsableOpenAICredential(apiKey) &&
isCanonicalConcentrateInferenceBaseUrl(process.env.OPENAI_BASE_URL)
) {
process.env.OPENAI_API_KEY = apiKey
} else {
delete process.env.OPENAI_API_KEY
}
delete process.env.OPENAI_API_FORMAT
delete process.env.OPENAI_AZURE_STYLE
delete process.env.OPENAI_AUTH_HEADER
delete process.env.OPENAI_AUTH_SCHEME
delete process.env.OPENAI_AUTH_HEADER_VALUE
delete process.env.ANTHROPIC_CUSTOM_HEADERS
}
function usableProviderConfigEnvValue(
value: string | undefined,
): string | undefined {
@@ -512,6 +550,41 @@ export async function getAnthropicClient({
? 'max'
: standardEffortToOpenAI(appliedEffortLevel))
: undefined
// Normalize env-only routes before snapshotting custom headers. Dedicated
// routes such as Concentrate deliberately clear inherited proxy headers;
// doing that after getCustomHeaders() would leave a copied secret in the
// request defaults.
const envOnlyProviderRouteId = resolveEnvOnlyProviderRouteId(process.env)
const useMiniMaxEnvOnlyProvider = shouldUseMiniMaxEnvOnlyProvider(
model,
envOnlyProviderRouteId,
)
const useXiaomiMimoEnvOnlyProvider =
envOnlyProviderRouteId === 'xiaomi-mimo' && !useMiniMaxEnvOnlyProvider
const useXaiEnvOnlyProvider =
envOnlyProviderRouteId === 'xai' && !useMiniMaxEnvOnlyProvider
const useNearaiEnvOnlyProvider =
envOnlyProviderRouteId === 'nearai' && !useMiniMaxEnvOnlyProvider
const useFireworksEnvOnlyProvider =
envOnlyProviderRouteId === 'fireworks' && !useMiniMaxEnvOnlyProvider
const useLongcatEnvOnlyProvider =
envOnlyProviderRouteId === 'longcat' && !useMiniMaxEnvOnlyProvider
const useAimlapiEnvOnlyProvider =
envOnlyProviderRouteId === 'aimlapi' && !useMiniMaxEnvOnlyProvider
const useApismartEnvOnlyProvider =
envOnlyProviderRouteId === 'apismart' && !useMiniMaxEnvOnlyProvider
const useConcentrateEnvOnlyProvider =
envOnlyProviderRouteId === 'concentrate' && !useMiniMaxEnvOnlyProvider
if (useMiniMaxEnvOnlyProvider) applyMiniMaxEnvOnlyDefaults(model)
if (useXiaomiMimoEnvOnlyProvider) applyXiaomiMimoEnvOnlyDefaults()
if (useXaiEnvOnlyProvider) applyXaiEnvOnlyDefaults()
if (useNearaiEnvOnlyProvider) applyNearaiEnvOnlyDefaults()
if (useFireworksEnvOnlyProvider) applyFireworksEnvOnlyDefaults()
if (useLongcatEnvOnlyProvider) applyLongcatEnvOnlyDefaults()
if (useAimlapiEnvOnlyProvider) applyAimlapiEnvOnlyDefaults()
if (useApismartEnvOnlyProvider) applyApismartEnvOnlyDefaults()
if (useConcentrateEnvOnlyProvider) applyConcentrateEnvOnlyDefaults()
const containerId = process.env.CLAUDE_CODE_CONTAINER_ID
const remoteSessionId = process.env.CLAUDE_CODE_REMOTE_SESSION_ID
const clientApp = process.env.CLAUDE_AGENT_SDK_CLIENT_APP
@@ -542,50 +615,6 @@ export async function getAnthropicClient({
defaultHeaders['x-anthropic-additional-protection'] = 'true'
}
const envOnlyProviderRouteId = resolveEnvOnlyProviderRouteId(process.env)
const useMiniMaxEnvOnlyProvider = shouldUseMiniMaxEnvOnlyProvider(
model,
envOnlyProviderRouteId,
)
const useXiaomiMimoEnvOnlyProvider =
envOnlyProviderRouteId === 'xiaomi-mimo' && !useMiniMaxEnvOnlyProvider
const useXaiEnvOnlyProvider =
envOnlyProviderRouteId === 'xai' && !useMiniMaxEnvOnlyProvider
const useNearaiEnvOnlyProvider =
envOnlyProviderRouteId === 'nearai' && !useMiniMaxEnvOnlyProvider
const useFireworksEnvOnlyProvider =
envOnlyProviderRouteId === 'fireworks' && !useMiniMaxEnvOnlyProvider
const useLongcatEnvOnlyProvider =
envOnlyProviderRouteId === 'longcat' && !useMiniMaxEnvOnlyProvider
const useAimlapiEnvOnlyProvider =
envOnlyProviderRouteId === 'aimlapi' && !useMiniMaxEnvOnlyProvider
const useApismartEnvOnlyProvider =
envOnlyProviderRouteId === 'apismart' && !useMiniMaxEnvOnlyProvider
if (useMiniMaxEnvOnlyProvider) {
applyMiniMaxEnvOnlyDefaults(model)
}
if (useXiaomiMimoEnvOnlyProvider) {
applyXiaomiMimoEnvOnlyDefaults()
}
if (useXaiEnvOnlyProvider) {
applyXaiEnvOnlyDefaults()
}
if (useNearaiEnvOnlyProvider) {
applyNearaiEnvOnlyDefaults()
}
if (useFireworksEnvOnlyProvider) {
applyFireworksEnvOnlyDefaults()
}
if (useLongcatEnvOnlyProvider) {
applyLongcatEnvOnlyDefaults()
}
if (useAimlapiEnvOnlyProvider) {
applyAimlapiEnvOnlyDefaults()
}
if (useApismartEnvOnlyProvider) {
applyApismartEnvOnlyDefaults()
}
const apiProvider = getAPIProvider()
const isFirstPartyBaseUrl = isFirstPartyAnthropicBaseUrl()
const shouldUseFirstPartyAuth = shouldUseFirstPartyAnthropicAuthForProvider({
@@ -690,6 +719,7 @@ export async function getAnthropicClient({
useFireworksEnvOnlyProvider ||
useAimlapiEnvOnlyProvider ||
useApismartEnvOnlyProvider ||
useConcentrateEnvOnlyProvider ||
isEnvTruthy(process.env.CLAUDE_CODE_USE_OPENAI) ||
isEnvTruthy(process.env.CLAUDE_CODE_USE_GITHUB) ||
isEnvTruthy(process.env.CLAUDE_CODE_USE_GEMINI) ||
@@ -50,6 +50,9 @@ const originalEnv = {
OPENROUTER_API_KEY: process.env.OPENROUTER_API_KEY,
DEEPSEEK_API_KEY: process.env.DEEPSEEK_API_KEY,
MIMO_API_KEY: process.env.MIMO_API_KEY,
CONCENTRATE_API_KEY: process.env.CONCENTRATE_API_KEY,
CONCENTRATE_BASE_URL: process.env.CONCENTRATE_BASE_URL,
CONCENTRATE_MODEL: process.env.CONCENTRATE_MODEL,
OPENGATEWAY_API_KEY: process.env.OPENGATEWAY_API_KEY,
OPENGATEWAY_BASE_URL: process.env.OPENGATEWAY_BASE_URL,
OPENCODE_API_KEY: process.env.OPENCODE_API_KEY,
@@ -471,6 +474,9 @@ beforeEach(async () => {
delete process.env.OPENROUTER_API_KEY
delete process.env.DEEPSEEK_API_KEY
delete process.env.MIMO_API_KEY
delete process.env.CONCENTRATE_API_KEY
delete process.env.CONCENTRATE_BASE_URL
delete process.env.CONCENTRATE_MODEL
delete process.env.OPENGATEWAY_API_KEY
delete process.env.OPENGATEWAY_BASE_URL
delete process.env.OPENCODE_API_KEY
@@ -517,6 +523,9 @@ afterEach(() => {
restoreEnv('OPENROUTER_API_KEY', originalEnv.OPENROUTER_API_KEY)
restoreEnv('DEEPSEEK_API_KEY', originalEnv.DEEPSEEK_API_KEY)
restoreEnv('MIMO_API_KEY', originalEnv.MIMO_API_KEY)
restoreEnv('CONCENTRATE_API_KEY', originalEnv.CONCENTRATE_API_KEY)
restoreEnv('CONCENTRATE_BASE_URL', originalEnv.CONCENTRATE_BASE_URL)
restoreEnv('CONCENTRATE_MODEL', originalEnv.CONCENTRATE_MODEL)
restoreEnv('OPENGATEWAY_API_KEY', originalEnv.OPENGATEWAY_API_KEY)
restoreEnv('OPENGATEWAY_BASE_URL', originalEnv.OPENGATEWAY_BASE_URL)
restoreEnv('OPENCODE_API_KEY', originalEnv.OPENCODE_API_KEY)
@@ -547,6 +556,20 @@ test('gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic
expect(captured.authorization).toBe('Bearer fake-ogw-key')
})
test('Concentrate selection prefers its dedicated key over a generic OPENAI_API_KEYS pool', async () => {
process.env.CONCENTRATE_API_KEY = 'concentrate-key'
process.env.OPENAI_API_KEYS = 'generic-openai-key-a,generic-openai-key-b'
delete process.env.OPENAI_API_KEY
const result = applyProviderFlag('concentrate', [])
expect(result.error).toBeUndefined()
const captured = await captureChatCompletionRequest()
expect(captured.url).toBe('https://api.concentrate.ai/v1/chat/completions')
expect(captured.authorization).toBe('Bearer concentrate-key')
})
test('gitlawb opengateway provider flag uses generic OPENAI_API_KEYS pool before generic OPENAI_API_KEY fallback', async () => {
process.env.OPENGATEWAY_BASE_URL = 'http://localhost:8181/v1'
process.env.OPENAI_API_KEYS = 'fake-openai-pool-a,fake-openai-pool-b'
@@ -288,6 +288,7 @@ export async function executeOpenAIRequest(
requestProcessEnv.MINIMAX_API_KEY,
requestProcessEnv.ATLAS_CLOUD_API_KEY,
requestProcessEnv.APISMART_API_KEY,
requestProcessEnv.CONCENTRATE_API_KEY,
requestProcessEnv.NEARAI_API_KEY,
requestProcessEnv.FIREWORKS_API_KEY,
requestProcessEnv.LONGCAT_API_KEY,
+19
View File
@@ -292,6 +292,25 @@ describe('loadEnvFile', () => {
})
})
it('loads documented Concentrate env-only provider setup values', () => {
const filePath = writeTempEnvFile([
'CONCENTRATE_API_KEY=concentrate-key',
'CONCENTRATE_BASE_URL=https://api.concentrate.ai/v1',
'CONCENTRATE_MODEL=claude-sonnet-5',
].join('\n'))
const loaded = loadEnvFile(filePath)
expect(process.env.CONCENTRATE_API_KEY).toBe('concentrate-key')
expect(process.env.CONCENTRATE_BASE_URL).toBe('https://api.concentrate.ai/v1')
expect(process.env.CONCENTRATE_MODEL).toBe('claude-sonnet-5')
expect(loaded).toEqual({
CONCENTRATE_API_KEY: 'concentrate-key',
CONCENTRATE_BASE_URL: 'https://api.concentrate.ai/v1',
CONCENTRATE_MODEL: 'claude-sonnet-5',
})
})
it('loads documented Azure OpenAI API version values', () => {
const filePath = writeTempEnvFile(
'AZURE_OPENAI_API_VERSION=2024-12-01-preview',
+3
View File
@@ -49,6 +49,9 @@ const ALLOWED_ENV_FILE_KEYS = new Set([
'CODEX_AUTH_JSON_PATH',
'CODEX_CREDENTIAL_SOURCE',
'CODEX_HOME',
'CONCENTRATE_API_KEY',
'CONCENTRATE_BASE_URL',
'CONCENTRATE_MODEL',
'DASHSCOPE_API_KEY',
'DEEPSEEK_API_KEY',
'EXA_API_KEY',
@@ -14,6 +14,8 @@ import {
clearPluginSettingsBase,
resetSettingsCache,
} from '../settings/settingsCache.js'
let allowedModels: Set<string> | undefined
async function importFreshModelModule() {
mock.restore()
const getAPIProvider = () => {
@@ -44,7 +46,7 @@ async function importFreshModelModule() {
getAPIProvider() === 'firstParty' && !!process.env.ANTHROPIC_BASE_URL,
}))
mock.module('./modelAllowlist.js', () => ({
isModelAllowed: () => true,
isModelAllowed: (model: string) => allowedModels?.has(model) ?? true,
}))
const nonce = `${Date.now()}-${Math.random()}`
return import(`./model.js?ts=${nonce}`)
@@ -75,6 +77,9 @@ const SAVED_ENV = {
ANTHROPIC_MODEL: process.env.ANTHROPIC_MODEL,
ANTHROPIC_BASE_URL: process.env.ANTHROPIC_BASE_URL,
MIMO_API_KEY: process.env.MIMO_API_KEY,
CONCENTRATE_API_KEY: process.env.CONCENTRATE_API_KEY,
CONCENTRATE_BASE_URL: process.env.CONCENTRATE_BASE_URL,
CONCENTRATE_MODEL: process.env.CONCENTRATE_MODEL,
OPENAI_MODEL: process.env.OPENAI_MODEL,
OPENAI_BASE_URL: process.env.OPENAI_BASE_URL,
CODEX_API_KEY: process.env.CODEX_API_KEY,
@@ -122,6 +127,7 @@ beforeEach(async () => {
resetStateForTests()
resetSettingsCache()
clearPluginSettingsBase()
allowedModels = undefined
delete process.env.CLAUDE_CODE_USE_OPENAI
delete process.env.CLAUDE_CODE_USE_GEMINI
delete process.env.CLAUDE_CODE_USE_GITHUB
@@ -133,6 +139,9 @@ beforeEach(async () => {
delete process.env.MINIMAX_API_KEY
delete process.env.ANTHROPIC_MODEL
delete process.env.MIMO_API_KEY
delete process.env.CONCENTRATE_API_KEY
delete process.env.CONCENTRATE_BASE_URL
delete process.env.CONCENTRATE_MODEL
delete process.env.OPENAI_MODEL
delete process.env.OPENAI_BASE_URL
delete process.env.CODEX_API_KEY
@@ -340,6 +349,91 @@ test('getDefaultMainLoopModelSetting defaults MiniMax to M3', async () => {
expect(getDefaultMainLoopModel()).toBe('MiniMax-M3')
})
test('Concentrate selects its dedicated model before client normalization', async () => {
// getMainLoopModel runs before getAnthropicClient mirrors Concentrate into
// OPENAI_MODEL. A saved model must not win during that interval.
saveGlobalConfig(current => ({ ...current, model: 'stale-other-provider-model' }))
process.env.CONCENTRATE_API_KEY = 'concentrate-test'
process.env.CONCENTRATE_MODEL = 'claude-sonnet-5'
const {
getDefaultMainLoopModelSetting,
getMainLoopModel,
getUserSpecifiedModelSetting,
} = await importFreshModelModule()
expect(getUserSpecifiedModelSetting()).toBe('claude-sonnet-5')
expect(getDefaultMainLoopModelSetting()).toBe('claude-sonnet-5')
expect(getMainLoopModel()).toBe('claude-sonnet-5')
})
test('Concentrate honors its legacy OpenAI model fallback before client normalization', async () => {
saveGlobalConfig(current => ({ ...current, model: 'stale-other-provider-model' }))
process.env.CONCENTRATE_API_KEY = 'concentrate-test'
process.env.OPENAI_MODEL = 'legacy-concentrate-model'
const { getMainLoopModel, getUserSpecifiedModelSetting } =
await importFreshModelModule()
expect(getUserSpecifiedModelSetting()).toBe('legacy-concentrate-model')
expect(getMainLoopModel()).toBe('legacy-concentrate-model')
})
test('Concentrate skips a discovered-model rejection to its OpenAI fallback', async () => {
allowedModels = new Set(['legacy-concentrate-model'])
process.env.CONCENTRATE_API_KEY = 'concentrate-test'
process.env.CONCENTRATE_MODEL = 'rejected-concentrate-model'
process.env.OPENAI_MODEL = 'legacy-concentrate-model'
const {
getDefaultMainLoopModelSetting,
getMainLoopModel,
getUserSpecifiedModelSetting,
} = await importFreshModelModule()
expect(getUserSpecifiedModelSetting()).toBe('legacy-concentrate-model')
expect(getDefaultMainLoopModelSetting()).toBe('legacy-concentrate-model')
expect(getMainLoopModel()).toBe('legacy-concentrate-model')
})
test('Concentrate falls back to its route default when configured models are rejected', async () => {
allowedModels = new Set()
process.env.CONCENTRATE_API_KEY = 'concentrate-test'
process.env.CONCENTRATE_MODEL = 'rejected-concentrate-model'
process.env.OPENAI_MODEL = 'also-rejected-model'
const {
getDefaultMainLoopModelSetting,
getMainLoopModel,
getUserSpecifiedModelSetting,
} = await importFreshModelModule()
expect(getUserSpecifiedModelSetting()).toBeUndefined()
expect(getDefaultMainLoopModelSetting()).toBe('deepseek-v4-flash')
expect(getMainLoopModel()).toBe('deepseek-v4-flash')
})
test('Concentrate uses its descriptor default before client normalization', async () => {
process.env.CONCENTRATE_API_KEY = 'concentrate-test'
const { getDefaultMainLoopModelSetting } = await importFreshModelModule()
expect(getDefaultMainLoopModelSetting()).toBe('deepseek-v4-flash')
})
test.each(['null', 'undefined', ' '])(
'Concentrate ignores unusable dedicated model value %p before client normalization',
async value => {
saveGlobalConfig(current => ({ ...current, model: 'stale-other-provider-model' }))
process.env.CONCENTRATE_API_KEY = 'concentrate-test'
process.env.CONCENTRATE_MODEL = value
const {
getDefaultMainLoopModelSetting,
getMainLoopModel,
getUserSpecifiedModelSetting,
} = await importFreshModelModule()
expect(getUserSpecifiedModelSetting()).toBeUndefined()
expect(getDefaultMainLoopModelSetting()).toBe('deepseek-v4-flash')
expect(getMainLoopModel()).toBe('deepseek-v4-flash')
},
)
test('getDefaultMainLoopModelSetting uses the NVIDIA NIM route model', async () => {
process.env.NVIDIA_NIM = '1'
process.env.CLAUDE_CODE_USE_OPENAI = '1'
+40 -9
View File
@@ -35,7 +35,7 @@ import { type ModelAlias, isModelAlias } from './aliases.js'
import { capitalize } from '../stringUtils.js'
import { DEFAULT_GEMINI_MODEL } from '../providerProfile.js'
import { getAntModelOverrideConfig, resolveAntModel } from './antModels.js'
import { getRouteDefaultModel } from '../../integrations/routeMetadata.js'
import { getRouteDefaultModel, resolveActiveRouteIdFromEnv } from '../../integrations/routeMetadata.js'
export type ModelShortName = string
export type ModelName = string
@@ -51,6 +51,24 @@ function normalizeModelSetting(value: unknown): ModelName | ModelAlias | undefin
return trimmed.length > 0 ? trimmed : undefined
}
function getUsableProviderConfigModel(value: string | undefined): string | undefined {
const normalized = normalizeModelSetting(value)
if (!normalized) return undefined
const lowercase = normalized.toLowerCase()
return lowercase === 'undefined' || lowercase === 'null' ? undefined : normalized
}
function getAllowedConcentrateConfigModel(): string | undefined {
for (const value of [
process.env.CONCENTRATE_MODEL,
process.env.OPENAI_MODEL,
]) {
const model = getUsableProviderConfigModel(value)
if (model && isModelAllowed(model)) return model
}
return undefined
}
export function getSmallFastModel(): ModelName {
if (process.env.ANTHROPIC_SMALL_FAST_MODEL) return process.env.ANTHROPIC_SMALL_FAST_MODEL
if (isCustomAnthropicProvider()) {
@@ -140,6 +158,7 @@ export function getUserSpecifiedModelSetting(): ModelSetting | undefined {
// settings.model, so switching from (say) Moonshot to Codex kept firing
// `kimi-k2.6` at the Codex endpoint and getting 400s.
const provider = getAPIProvider()
const activeRouteId = resolveActiveRouteIdFromEnv(process.env)
const isOpenAIShimProvider =
provider === 'openai' ||
provider === 'codex' ||
@@ -148,14 +167,19 @@ export function getUserSpecifiedModelSetting(): ModelSetting | undefined {
provider === 'minimax' ||
provider === 'xiaomi-mimo' ||
provider === 'xai'
specifiedModel =
(provider === 'gemini' ? process.env.GEMINI_MODEL : undefined) ||
(provider === 'mistral' ? process.env.MISTRAL_MODEL : undefined) ||
(provider === 'minimax' ? getMiniMaxModelEnv() : undefined) ||
(isOpenAIShimProvider ? process.env.OPENAI_MODEL : undefined) ||
(provider === 'firstParty' ? process.env.ANTHROPIC_MODEL : undefined) ||
setting ||
undefined
specifiedModel = activeRouteId === 'concentrate'
// Concentrate is an env-only OpenAI-compatible route. Model selection
// happens before the client applies its OpenAI-compatible defaults, so
// consume its dedicated setting here rather than falling through to a
// saved model from an unrelated provider.
? getAllowedConcentrateConfigModel()
: (provider === 'gemini' ? process.env.GEMINI_MODEL : undefined) ||
(provider === 'mistral' ? process.env.MISTRAL_MODEL : undefined) ||
(provider === 'minimax' ? getMiniMaxModelEnv() : undefined) ||
(isOpenAIShimProvider ? process.env.OPENAI_MODEL : undefined) ||
(provider === 'firstParty' ? process.env.ANTHROPIC_MODEL : undefined) ||
setting ||
undefined
}
// Ignore the user-specified model if it's not in the availableModels allowlist.
@@ -373,6 +397,13 @@ export function getRuntimeMainLoopModel(params: {
* @returns The default model setting to use
*/
export function getDefaultMainLoopModelSetting(): ModelName | ModelAlias {
if (resolveActiveRouteIdFromEnv(process.env) === 'concentrate') {
return (
getAllowedConcentrateConfigModel() ||
getRouteDefaultModel('concentrate') ||
'deepseek-v4-flash'
)
}
// Custom Anthropic-compatible endpoints intentionally retain the legacy
// firstParty provider category, so prefer their explicitly configured model
// before the subscription and PAYG defaults below.
+167
View File
@@ -13,6 +13,7 @@ import {
applyModelFlagFromArgs,
VALID_PROVIDERS,
} from './providerFlag.js'
import { resolveActiveRouteIdFromEnv } from '../integrations/routeMetadata.js'
const ENV_KEYS = [
'CLAUDE_CODE_USE_OPENAI',
@@ -42,6 +43,9 @@ const ENV_KEYS = [
'ATLAS_CLOUD_API_KEY',
'APISMART_API_KEY',
'APISMART_MODEL',
'CONCENTRATE_API_KEY',
'CONCENTRATE_BASE_URL',
'CONCENTRATE_MODEL',
'LONGCAT_API_KEY',
'OPENGATEWAY_API_KEY',
'OPENGATEWAY_BASE_URL',
@@ -93,6 +97,9 @@ const RESET_KEYS = [
'ATLAS_CLOUD_API_KEY',
'APISMART_API_KEY',
'APISMART_MODEL',
'CONCENTRATE_API_KEY',
'CONCENTRATE_BASE_URL',
'CONCENTRATE_MODEL',
'LONGCAT_API_KEY',
'OPENGATEWAY_API_KEY',
'OPENGATEWAY_BASE_URL',
@@ -201,6 +208,16 @@ describe('applyProviderFlag - anthropic', () => {
expect(process.env.APISMART_API_KEY).toBeUndefined()
expect(process.env.APISMART_MODEL).toBeUndefined()
})
test('does not leave Concentrate env-only selection active', () => {
process.env.CONCENTRATE_API_KEY = 'concentrate-key'
process.env.CONCENTRATE_BASE_URL = 'https://api.concentrate.ai/v1'
process.env.CONCENTRATE_MODEL = 'claude-sonnet-5'
applyProviderFlag('anthropic', [])
expect(process.env.CONCENTRATE_API_KEY).toBeUndefined()
expect(process.env.CONCENTRATE_BASE_URL).toBeUndefined()
expect(process.env.CONCENTRATE_MODEL).toBeUndefined()
})
})
describe('applyProviderFlag - custom Anthropic-compatible', () => {
@@ -261,6 +278,21 @@ describe('applyProviderFlag - custom Anthropic-compatible', () => {
expect(process.env.ANTHROPIC_MODEL).toBe('proxy-model')
})
test('does not leave Concentrate env-only selection active', () => {
process.env.ANTHROPIC_BASE_URL = 'https://proxy.example/v1'
process.env.ANTHROPIC_AUTH_TOKEN = 'proxy-token'
process.env.CONCENTRATE_API_KEY = 'concentrate-key'
process.env.CONCENTRATE_BASE_URL = 'https://api.concentrate.ai/v1'
process.env.CONCENTRATE_MODEL = 'claude-sonnet-5'
const result = applyProviderFlag('custom-anthropic', [])
expect(result.error).toBeUndefined()
expect(process.env.CONCENTRATE_API_KEY).toBeUndefined()
expect(process.env.CONCENTRATE_BASE_URL).toBeUndefined()
expect(process.env.CONCENTRATE_MODEL).toBeUndefined()
})
test('accepts native x-api-key authentication', () => {
process.env.ANTHROPIC_BASE_URL = 'https://proxy.example/v1'
process.env.ANTHROPIC_API_KEY = 'stale-first-party-key'
@@ -309,6 +341,16 @@ describe('applyProviderFlag - openai', () => {
expect(process.env.APISMART_API_KEY).toBeUndefined()
expect(process.env.APISMART_MODEL).toBeUndefined()
})
test('does not leave Concentrate env-only selection active', () => {
process.env.CONCENTRATE_API_KEY = 'concentrate-key'
process.env.CONCENTRATE_BASE_URL = 'https://api.concentrate.ai/v1'
process.env.CONCENTRATE_MODEL = 'claude-sonnet-5'
applyProviderFlag('openai', [])
expect(process.env.CONCENTRATE_API_KEY).toBeUndefined()
expect(process.env.CONCENTRATE_BASE_URL).toBeUndefined()
expect(process.env.CONCENTRATE_MODEL).toBeUndefined()
})
})
describe('applyProviderFlag - cloudflare', () => {
@@ -1309,3 +1351,128 @@ describe('applyModelFlagFromArgs', () => {
expect(process.env.OPENAI_MODEL).toBe('qwen2.5-coder:14b')
})
})
describe('applyProviderFlag - concentrate', () => {
test('sets Concentrate OpenAI-compatible defaults and mirrors CONCENTRATE_API_KEY', () => {
process.env.CONCENTRATE_API_KEY = 'concentrate-secret-key'
const result = applyProviderFlag('concentrate', [])
expect(result.error).toBeUndefined()
expect(process.env.CLAUDE_CODE_USE_OPENAI).toBe('1')
expect(process.env.OPENAI_BASE_URL).toBe('https://api.concentrate.ai/v1')
expect(process.env.OPENAI_MODEL).toBe('deepseek-v4-flash')
expect(process.env.OPENAI_API_KEY).toBe('concentrate-secret-key')
})
test('uses CONCENTRATE_BASE_URL and CONCENTRATE_MODEL from env', () => {
process.env.CONCENTRATE_API_KEY = 'concentrate-secret-key'
process.env.CONCENTRATE_BASE_URL = 'https://api.concentrate.ai/v1'
process.env.CONCENTRATE_MODEL = 'claude-sonnet-5'
applyProviderFlag('concentrate', [])
expect(process.env.OPENAI_BASE_URL).toBe('https://api.concentrate.ai/v1')
expect(process.env.OPENAI_MODEL).toBe('claude-sonnet-5')
})
test('does not mirror the dedicated key to a noncanonical Concentrate URL', () => {
process.env.CONCENTRATE_API_KEY = 'concentrate-secret-key'
process.env.CONCENTRATE_BASE_URL = 'https://api.concentrate.ai/staging/v1'
applyProviderFlag('concentrate', [])
expect(process.env.OPENAI_BASE_URL).toBe('https://api.concentrate.ai/staging/v1')
expect(process.env.OPENAI_API_KEY).toBeUndefined()
})
test('explicit --model overrides CONCENTRATE_MODEL and OPENAI_MODEL', () => {
process.env.CONCENTRATE_API_KEY = 'concentrate-secret-key'
process.env.CONCENTRATE_MODEL = 'claude-sonnet-5'
applyProviderFlag('concentrate', ['--model', 'deepseek-v4-pro-0731'])
expect(process.env.OPENAI_MODEL).toBe('deepseek-v4-pro-0731')
expect(process.env.CONCENTRATE_MODEL).toBeUndefined()
})
test('dedicated key overrides a lingering OPENAI_API_KEY from another provider', () => {
process.env.OPENAI_API_KEY = 'existing-openai-key'
process.env.CONCENTRATE_API_KEY = 'concentrate-secret-key'
applyProviderFlag('concentrate', [])
expect(process.env.OPENAI_API_KEY).toBe('concentrate-secret-key')
})
test('clears a stale OPENAI_API_KEY when no Concentrate key is set', () => {
delete process.env.CONCENTRATE_API_KEY
process.env.OPENAI_API_KEY = 'existing-openai-key'
applyProviderFlag('concentrate', [])
expect(process.env.OPENAI_API_KEY).toBeUndefined()
})
test.each(['SUA_CHAVE', 'sua_chave', 'null', 'undefined', ' NULL '])(
'does not mirror placeholder Concentrate credential %s',
placeholder => {
process.env.CONCENTRATE_API_KEY = placeholder
applyProviderFlag('concentrate', [])
expect(process.env.OPENAI_API_KEY).toBeUndefined()
},
)
test('clears a copied Concentrate key from OPENAI_API_KEY when switching to another provider', () => {
process.env.CONCENTRATE_API_KEY = 'concentrate-secret-key'
process.env.OPENAI_API_KEY = 'concentrate-secret-key'
applyProviderFlag('openai', [])
expect(process.env.OPENAI_API_KEY).toBeUndefined()
})
test('switching from Concentrate to Ollama replaces the route identity and credentials', () => {
process.env.CONCENTRATE_API_KEY = 'concentrate-secret-key'
applyProviderFlag('concentrate', [])
applyProviderFlag('ollama', [])
expect(process.env.CONCENTRATE_API_KEY).toBeUndefined()
expect(process.env.CONCENTRATE_BASE_URL).toBeUndefined()
expect(process.env.CONCENTRATE_MODEL).toBeUndefined()
expect(process.env.OPENAI_BASE_URL).toBe('http://localhost:11434/v1')
expect(process.env.OPENAI_API_KEY).toBe('ollama')
expect(resolveActiveRouteIdFromEnv(process.env)).toBe('ollama')
})
test('switching from Concentrate to OpenAI replaces the known gateway endpoint', () => {
process.env.CONCENTRATE_API_KEY = 'concentrate-secret-key'
applyProviderFlag('concentrate', [])
applyProviderFlag('openai', [])
expect(process.env.CONCENTRATE_API_KEY).toBeUndefined()
expect(process.env.OPENAI_BASE_URL).toBe('https://api.openai.com/v1')
expect(resolveActiveRouteIdFromEnv(process.env)).toBe('openai')
})
test('clears unsupported OpenAI shim settings from a previous route', () => {
process.env.CONCENTRATE_API_KEY = 'concentrate-secret-key'
process.env.OPENAI_API_FORMAT = 'responses'
process.env.OPENAI_AUTH_HEADER = 'x-api-key'
process.env.OPENAI_AUTH_SCHEME = 'raw'
process.env.OPENAI_AUTH_HEADER_VALUE = 'stale-value'
process.env.ANTHROPIC_CUSTOM_HEADERS = 'X-Proxy-Auth: proxy-secret'
applyProviderFlag('concentrate', [])
expect(process.env.OPENAI_API_FORMAT).toBeUndefined()
expect(process.env.OPENAI_AUTH_HEADER).toBeUndefined()
expect(process.env.OPENAI_AUTH_SCHEME).toBeUndefined()
expect(process.env.OPENAI_AUTH_HEADER_VALUE).toBeUndefined()
expect(process.env.ANTHROPIC_CUSTOM_HEADERS).toBeUndefined()
})
})
+115 -20
View File
@@ -29,7 +29,10 @@ import {
resolveRouteIdFromBaseUrl,
} from '../integrations/index.js'
import { PRESET_VENDOR_MAP } from '../integrations/compatibility.js'
import { isCanonicalApismartInferenceBaseUrl } from '../integrations/routeMetadata.js'
import {
isCanonicalApismartInferenceBaseUrl,
isCanonicalConcentrateInferenceBaseUrl,
} from '../integrations/routeMetadata.js'
import { hasUsableOpenAICredential } from '../services/api/credentialPool.js'
import { isFirstPartyAnthropicBaseUrlForEnv } from './anthropicBaseUrl.js'
@@ -203,7 +206,6 @@ function shouldReplaceStaleKnownBaseUrl(provider: string): boolean {
const targetRouteId = resolveProfileRoute(provider).routeId
return (
targetRouteId !== 'openai' &&
targetRouteId !== 'custom' &&
targetRouteId !== 'unknown-fallback' &&
currentRouteId !== targetRouteId
@@ -252,6 +254,12 @@ function clearUnsupportedOpenAIShimSettings(routeId: string): void {
}
}
function clearConcentrateProviderState(): void {
delete process.env.CONCENTRATE_API_KEY
delete process.env.CONCENTRATE_BASE_URL
delete process.env.CONCENTRATE_MODEL
}
function usableProviderModelEnvValue(
value: string | undefined,
): string | undefined {
@@ -350,18 +358,21 @@ export function applyProviderFlag(
: process.env.OPENAI_API_KEY !== undefined &&
process.env.OPENAI_API_KEY === process.env.ATLAS_CLOUD_API_KEY
? 'atlas-cloud'
: process.env.OPENAI_API_KEY !== undefined &&
process.env.OPENAI_API_KEY === process.env.APISMART_API_KEY
? 'apismart'
: process.env.OPENAI_API_KEY !== undefined &&
process.env.OPENAI_API_KEY === process.env.NEARAI_API_KEY
? 'nearai'
: process.env.OPENAI_API_KEY !== undefined &&
process.env.OPENAI_API_KEY === process.env.FIREWORKS_API_KEY
? 'fireworks'
: process.env.OPENAI_API_KEY !== undefined &&
process.env.OPENAI_API_KEY === process.env.LONGCAT_API_KEY
? 'longcat'
process.env.OPENAI_API_KEY === process.env.APISMART_API_KEY
? 'apismart'
: process.env.OPENAI_API_KEY !== undefined &&
process.env.OPENAI_API_KEY === process.env.CONCENTRATE_API_KEY
? 'concentrate'
: process.env.OPENAI_API_KEY !== undefined &&
process.env.OPENAI_API_KEY === process.env.NEARAI_API_KEY
? 'nearai'
: process.env.OPENAI_API_KEY !== undefined &&
process.env.OPENAI_API_KEY === process.env.FIREWORKS_API_KEY
? 'fireworks'
: process.env.OPENAI_API_KEY !== undefined &&
process.env.OPENAI_API_KEY === process.env.LONGCAT_API_KEY
? 'longcat'
: process.env.OPENAI_API_KEY !== undefined &&
opengatewayApiKey !== undefined &&
opengatewayApiKey.length > 0 &&
@@ -455,9 +466,11 @@ export function applyProviderFlag(
case 'openai':
process.env.CLAUDE_CODE_USE_OPENAI = '1'
// An explicit generic OpenAI selection must not be reclassified as a
// dedicated env-only gateway during client startup.
// dedicated env-only gateway during client startup. Replace a previous
// known gateway endpoint, but preserve a user-supplied custom endpoint.
delete process.env.APISMART_API_KEY
delete process.env.APISMART_MODEL
applyOpenAIBaseUrlDefault(provider, defaultBaseUrl)
if (model) process.env.OPENAI_MODEL = model
break
@@ -486,7 +499,10 @@ export function applyProviderFlag(
case 'ollama':
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.OPENAI_BASE_URL ??= defaultBaseUrl ?? 'http://localhost:11434/v1'
applyOpenAIBaseUrlDefault(
provider,
defaultBaseUrl ?? 'http://localhost:11434/v1',
)
if (!process.env.OPENAI_API_KEY) {
process.env.OPENAI_API_KEY = 'ollama'
}
@@ -495,7 +511,10 @@ export function applyProviderFlag(
case 'nvidia-nim':
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.OPENAI_BASE_URL ??= defaultBaseUrl ?? 'https://integrate.api.nvidia.com/v1'
applyOpenAIBaseUrlDefault(
provider,
defaultBaseUrl ?? 'https://integrate.api.nvidia.com/v1',
)
process.env.NVIDIA_NIM = '1'
if (process.env.NVIDIA_API_KEY && !process.env.OPENAI_API_KEY) {
process.env.OPENAI_API_KEY = process.env.NVIDIA_API_KEY
@@ -506,7 +525,10 @@ export function applyProviderFlag(
case 'bankr':
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.OPENAI_BASE_URL ??= defaultBaseUrl ?? 'https://llm.bankr.bot/v1'
applyOpenAIBaseUrlDefault(
provider,
defaultBaseUrl ?? 'https://llm.bankr.bot/v1',
)
process.env.OPENAI_MODEL ??= 'claude-opus-4.6'
if (model) process.env.OPENAI_MODEL = model
if (process.env.BNKR_API_KEY && !process.env.OPENAI_API_KEY) {
@@ -567,7 +589,7 @@ export function applyProviderFlag(
case 'xai':
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.OPENAI_BASE_URL ??= 'https://api.x.ai/v1'
applyOpenAIBaseUrlDefault(provider, defaultBaseUrl ?? 'https://api.x.ai/v1')
process.env.OPENAI_MODEL ??= defaultModel ?? 'grok-4.6'
if (model) process.env.OPENAI_MODEL = model
if (process.env.XAI_API_KEY && !process.env.OPENAI_API_KEY) {
@@ -577,7 +599,10 @@ export function applyProviderFlag(
case 'xiaomi-mimo':
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.OPENAI_BASE_URL ??= defaultBaseUrl ?? 'https://api.xiaomimimo.com/v1'
applyOpenAIBaseUrlDefault(
provider,
defaultBaseUrl ?? 'https://api.xiaomimimo.com/v1',
)
process.env.OPENAI_MODEL ??= defaultModel ?? 'mimo-v2.5-pro'
if (model) process.env.OPENAI_MODEL = model
if (process.env.MIMO_API_KEY && !process.env.OPENAI_API_KEY) {
@@ -600,7 +625,10 @@ export function applyProviderFlag(
case 'venice':
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.OPENAI_BASE_URL ??= defaultBaseUrl ?? 'https://api.venice.ai/api/v1'
applyOpenAIBaseUrlDefault(
provider,
defaultBaseUrl ?? 'https://api.venice.ai/api/v1',
)
process.env.OPENAI_MODEL ??= defaultModel ?? 'venice-uncensored'
if (model) process.env.OPENAI_MODEL = model
if (process.env.VENICE_API_KEY && !process.env.OPENAI_API_KEY) {
@@ -670,6 +698,62 @@ export function applyProviderFlag(
}
break
case 'concentrate':
process.env.CLAUDE_CODE_USE_OPENAI = '1'
// Concentrate uses the standard OpenAI-compatible wire contract with no
// alternate API formats or custom auth headers.
clearUnsupportedOpenAIShimSettings('concentrate')
delete process.env.ANTHROPIC_CUSTOM_HEADERS
{
const baseUrlOverride = usableProviderModelEnvValue(
process.env.CONCENTRATE_BASE_URL,
)
if (baseUrlOverride) {
process.env.OPENAI_BASE_URL = baseUrlOverride
} else {
// An explicit Concentrate selection must not retain an unrelated
// custom OpenAI endpoint from the preceding provider. Users can
// deliberately select a different Concentrate endpoint through
// CONCENTRATE_BASE_URL above.
process.env.OPENAI_BASE_URL =
defaultBaseUrl ?? 'https://api.concentrate.ai/v1'
}
}
{
const concentrateModel = usableProviderModelEnvValue(
process.env.CONCENTRATE_MODEL,
)
if (concentrateModel) {
process.env.OPENAI_MODEL = concentrateModel
} else {
process.env.OPENAI_MODEL ??=
usableProviderModelEnvValue(process.env.OPENAI_MODEL) ||
defaultModel ||
'deepseek-v4-flash'
}
}
if (model) {
// Runtime model resolution gives CONCENTRATE_MODEL priority over the
// shared shim setting. An explicit CLI selection must supersede that
// ambient provider default all the way through client normalization.
delete process.env.CONCENTRATE_MODEL
process.env.OPENAI_MODEL = model
}
// This explicit dedicated selection mirrors CONCENTRATE_API_KEY into the
// shared shim transport and clears a stale generic key. A generic
// OpenAI-compatible Concentrate setup remains supported when selected
// through OPENAI_BASE_URL instead. Do not mirror the dedicated key to a
// same-host proxy or alternate path supplied through CONCENTRATE_BASE_URL.
if (
hasUsableOpenAICredential(process.env.CONCENTRATE_API_KEY) &&
isCanonicalConcentrateInferenceBaseUrl(getConfiguredOpenAIBaseUrl())
) {
process.env.OPENAI_API_KEY = process.env.CONCENTRATE_API_KEY
} else {
delete process.env.OPENAI_API_KEY
}
break
case 'fireworks':
process.env.CLAUDE_CODE_USE_OPENAI = '1'
applyOpenAIBaseUrlDefault(provider, defaultBaseUrl)
@@ -760,5 +844,16 @@ export function applyProviderFlag(
break
}
// A provider flag selects a complete route for this process. Concentrate's
// dedicated variables are another source of route identity, so leaving them
// behind can re-select Concentrate after a later OpenAI-compatible provider
// has applied its defaults. Keep their lifecycle at the selection boundary,
// rather than relying on individual switch branches to remember cleanup.
// This runs only after the selected branch succeeds, so an invalid
// custom-anthropic request remains non-mutating.
if (provider !== 'concentrate') {
clearConcentrateProviderState()
}
return {}
}
+248
View File
@@ -18,6 +18,7 @@ import {
buildAtomicChatProfileEnv,
buildApismartProfileEnv,
buildCompatibilityProcessEnv,
buildConcentrateProfileEnv,
buildCodexProfileEnv,
buildGeminiProfileEnv,
buildLaunchEnv,
@@ -3012,3 +3013,250 @@ test('atomic-chat launch ignores mismatched persisted openai env', async () => {
assert.equal(env.CODEX_API_KEY, undefined)
assert.equal(env.CHATGPT_ACCOUNT_ID, undefined)
})
test('openai launch preserves persisted Concentrate dedicated credentials across restart', async () => {
const env = await buildLaunchEnv({
profile: 'openai',
persisted: profile('openai', {
OPENAI_BASE_URL: 'https://api.concentrate.ai/v1',
OPENAI_MODEL: 'deepseek-v4-flash-0731',
OPENAI_API_KEY: 'concentrate-secret-key',
CONCENTRATE_API_KEY: 'concentrate-secret-key',
}),
goal: 'coding',
processEnv: {},
})
assert.equal(env.OPENAI_BASE_URL, 'https://api.concentrate.ai/v1')
assert.equal(env.OPENAI_MODEL, 'deepseek-v4-flash-0731')
assert.equal(env.OPENAI_API_KEY, 'concentrate-secret-key')
assert.equal(env.CONCENTRATE_API_KEY, 'concentrate-secret-key')
assert.equal(env.CLAUDE_CODE_PROVIDER_ROUTE_ID, 'concentrate')
})
test('legacy generic OpenAI Concentrate profiles keep their credential generic', async () => {
const env = await buildLaunchEnv({
profile: 'openai',
persisted: profile('openai', {
OPENAI_BASE_URL: 'https://api.concentrate.ai/v1',
OPENAI_MODEL: 'deepseek-v4-flash-0731',
OPENAI_API_KEY: 'concentrate-secret-key',
}),
goal: 'coding',
processEnv: {},
})
assert.equal(env.CLAUDE_CODE_PROVIDER_ROUTE_ID, 'concentrate')
assert.equal(env.OPENAI_API_KEY, 'concentrate-secret-key')
assert.equal(env.CONCENTRATE_API_KEY, undefined)
assert.equal(
resolveRouteCredentialValue({
routeId: 'concentrate',
processEnv: env,
baseUrl: env.OPENAI_BASE_URL,
}),
'concentrate-secret-key',
)
})
test('openai launch keeps a generic Concentrate credential generic', async () => {
const env = await buildLaunchEnv({
profile: 'openai',
persisted: profile('openai', {
OPENAI_BASE_URL: 'https://api.concentrate.ai/v1',
OPENAI_MODEL: 'deepseek-v4-flash-0731',
CLAUDE_CODE_PROVIDER_ROUTE_ID: 'concentrate',
}),
goal: 'coding',
processEnv: {
OPENAI_API_KEY: 'generic-openai-key',
},
})
assert.equal(env.CONCENTRATE_API_KEY, undefined)
assert.equal(
resolveRouteCredentialValue({
routeId: 'concentrate',
processEnv: env,
baseUrl: env.OPENAI_BASE_URL,
}),
'generic-openai-key',
)
})
test('generic Concentrate profile lets a rotated OpenAI key override its saved key', async () => {
const env = await buildLaunchEnv({
profile: 'openai',
persisted: profile('openai', {
OPENAI_BASE_URL: 'https://api.concentrate.ai/v1',
OPENAI_MODEL: 'deepseek-v4-flash-0731',
OPENAI_API_KEY: 'saved-generic-key',
}),
goal: 'coding',
processEnv: {
OPENAI_API_KEY: 'rotated-generic-key',
},
})
assert.equal(env.OPENAI_API_KEY, 'rotated-generic-key')
assert.equal(env.CONCENTRATE_API_KEY, undefined)
assert.equal(
resolveRouteCredentialValue({
routeId: 'concentrate',
processEnv: env,
baseUrl: env.OPENAI_BASE_URL,
}),
'rotated-generic-key',
)
})
test('openai launch withholds ambient Concentrate credentials from a keyless proxy profile on restart', async () => {
const env = await buildLaunchEnv({
profile: 'openai',
persisted: profile('openai', {
CLAUDE_CODE_PROVIDER_ROUTE_ID: 'concentrate',
OPENAI_BASE_URL: 'https://proxy.example.com/v1',
OPENAI_MODEL: 'deepseek-v4-flash-0731',
}),
goal: 'coding',
processEnv: {
OPENAI_BASE_URL: 'https://proxy.example.com/v1',
OPENAI_API_KEY: 'ambient-concentrate-key',
CONCENTRATE_API_KEY: 'ambient-concentrate-key',
},
})
assert.equal(env.CLAUDE_CODE_PROVIDER_ROUTE_ID, 'concentrate')
assert.equal(env.OPENAI_API_KEY, undefined)
assert.equal(env.CONCENTRATE_API_KEY, undefined)
const canonical = await buildLaunchEnv({
profile: 'openai',
persisted: profile('openai', {
CLAUDE_CODE_PROVIDER_ROUTE_ID: 'concentrate',
OPENAI_BASE_URL: 'https://api.concentrate.ai/v1',
OPENAI_MODEL: 'deepseek-v4-flash-0731',
}),
goal: 'coding',
processEnv: {
OPENAI_BASE_URL: 'https://api.concentrate.ai/v1',
OPENAI_API_KEY: 'ambient-concentrate-key',
CONCENTRATE_API_KEY: 'ambient-concentrate-key',
},
})
assert.equal(canonical.OPENAI_API_KEY, 'ambient-concentrate-key')
assert.equal(canonical.CONCENTRATE_API_KEY, 'ambient-concentrate-key')
})
test('openai launch removes a legacy persisted Concentrate key from a noncanonical URL', async () => {
const env = await buildLaunchEnv({
profile: 'openai',
persisted: profile('openai', {
CLAUDE_CODE_PROVIDER_ROUTE_ID: 'concentrate',
OPENAI_BASE_URL: 'https://api.concentrate.ai/staging/v1',
OPENAI_MODEL: 'deepseek-v4-flash-0731',
CONCENTRATE_API_KEY: 'legacy-concentrate-key',
}),
goal: 'coding',
processEnv: {},
})
assert.equal(env.CLAUDE_CODE_PROVIDER_ROUTE_ID, 'concentrate')
assert.equal(env.OPENAI_API_KEY, undefined)
assert.equal(env.CONCENTRATE_API_KEY, undefined)
})
test('openai launch removes legacy generic credentials from a noncanonical Concentrate URL', async () => {
for (const [credentialEnvVar, credential] of [
['OPENAI_API_KEY', 'legacy-concentrate-key'],
['OPENAI_API_KEYS', 'legacy-concentrate-key-1,legacy-concentrate-key-2'],
] as const) {
const env = await buildLaunchEnv({
profile: 'openai',
persisted: profile('openai', {
CLAUDE_CODE_PROVIDER_ROUTE_ID: 'concentrate',
OPENAI_BASE_URL: 'https://api.concentrate.ai/staging/v1',
OPENAI_MODEL: 'deepseek-v4-flash-0731',
[credentialEnvVar]: credential,
}),
goal: 'coding',
processEnv: {},
})
assert.equal(env.OPENAI_API_KEY, undefined)
assert.equal(env.OPENAI_API_KEYS, undefined)
assert.equal(env.CONCENTRATE_API_KEY, undefined)
}
})
test('buildStartupEnvFromProfile preserves Concentrate env-only setup over a saved profile', async () => {
const env = await buildStartupEnvFromProfile({
persisted: profile('openai', {
OPENAI_BASE_URL: 'https://api.openai.com/v1',
OPENAI_MODEL: 'gpt-4o',
OPENAI_API_KEY: 'sk-persisted',
}),
goal: 'balanced',
processEnv: {
CONCENTRATE_API_KEY: 'concentrate-env-only-key',
CONCENTRATE_BASE_URL: 'https://api.concentrate.ai/v1',
CONCENTRATE_MODEL: 'claude-sonnet-5',
},
})
assert.equal(env.CONCENTRATE_API_KEY, 'concentrate-env-only-key')
assert.equal(env.CONCENTRATE_BASE_URL, 'https://api.concentrate.ai/v1')
assert.equal(env.CONCENTRATE_MODEL, 'claude-sonnet-5')
assert.equal(env.OPENAI_API_KEY, undefined)
assert.equal(resolveActiveRouteIdFromEnv(env), 'concentrate')
})
test('buildConcentrateProfileEnv prefers CONCENTRATE_MODEL over OPENAI_MODEL', () => {
const env = buildConcentrateProfileEnv({
apiKey: 'concentrate-secret-key',
processEnv: {
CONCENTRATE_MODEL: 'claude-sonnet-5',
OPENAI_MODEL: 'gpt-4o',
},
})
assert.ok(env)
assert.equal(env?.OPENAI_MODEL, 'claude-sonnet-5')
assert.equal(env?.CLAUDE_CODE_PROVIDER_ROUTE_ID, 'concentrate')
})
test('buildConcentrateProfileEnv reads CONCENTRATE_BASE_URL override', () => {
const env = buildConcentrateProfileEnv({
apiKey: 'concentrate-secret-key',
processEnv: {
CONCENTRATE_BASE_URL: 'https://api.concentrate.ai/v1',
},
})
assert.ok(env)
assert.equal(env?.OPENAI_BASE_URL, 'https://api.concentrate.ai/v1')
})
test('buildConcentrateProfileEnv refuses to serialize its credential for a noncanonical URL', () => {
const env = buildConcentrateProfileEnv({
apiKey: 'concentrate-secret-key',
processEnv: {
CONCENTRATE_BASE_URL: 'https://api.concentrate.ai/staging/v1',
},
})
assert.equal(env, null)
})
test('buildOpenAIProfileEnv does not stamp a generic key as Concentrate credentials on a noncanonical URL', () => {
const env = buildOpenAIProfileEnv({
goal: 'coding',
baseUrl: 'https://api.concentrate.ai/staging/v1',
apiKey: 'generic-proxy-key',
processEnv: {},
})
assert.ok(env)
assert.equal(env?.OPENAI_API_KEY, 'generic-proxy-key')
assert.equal(env?.CONCENTRATE_API_KEY, undefined)
})
+121 -12
View File
@@ -26,6 +26,7 @@ import {
getRouteDefaultBaseUrl,
getRouteDefaultModel,
isCanonicalApismartInferenceBaseUrl,
isCanonicalConcentrateInferenceBaseUrl,
isLongcatBaseUrl,
normalizeXiaomiMimoBaseUrl,
resolveRouteCredentialValue,
@@ -117,6 +118,9 @@ const PROFILE_ENV_KEYS = [
'NEARAI_API_KEY',
'FIREWORKS_API_KEY',
'LONGCAT_API_KEY',
'CONCENTRATE_API_KEY',
'CONCENTRATE_BASE_URL',
'CONCENTRATE_MODEL',
'CLINE_API_KEY',
'OPENCODE_API_KEY',
'CLAUDE_CODE_PROVIDER_ROUTE_ID',
@@ -204,6 +208,9 @@ export type ProfileEnv = {
NEARAI_API_KEY?: string
FIREWORKS_API_KEY?: string
LONGCAT_API_KEY?: string
CONCENTRATE_API_KEY?: string
CONCENTRATE_BASE_URL?: string
CONCENTRATE_MODEL?: string
OPENCODE_API_KEY?: string
CLOUDFLARE_API_TOKEN?: string
CLAUDE_CODE_OPENAI_CONTEXT_WINDOWS?: string
@@ -689,6 +696,61 @@ export function buildApismartProfileEnv(options: {
}
}
export function buildConcentrateProfileEnv(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.CONCENTRATE_API_KEY)
if (!key) {
return null
}
const defaultBaseUrl = getRouteDefaultBaseUrl('concentrate')
const defaultModel = getRouteDefaultModel('concentrate')
if (!defaultBaseUrl || !defaultModel) {
throw new Error('Concentrate route defaults are missing from integration metadata.')
}
const secretSource: SecretValueSource = {
OPENAI_API_KEY: key,
CONCENTRATE_API_KEY: key,
}
const configuredBaseUrl =
sanitizeProviderConfigValue(options.baseUrl, secretSource) ||
sanitizeProviderConfigValue(processEnv.CONCENTRATE_BASE_URL, secretSource) ||
sanitizeProviderConfigValue(processEnv.OPENAI_BASE_URL, secretSource)
// The dedicated credential belongs only to Concentrate's documented
// inference endpoint. Returning null lets the caller use its generic
// profile path without serializing this secret for a proxy or alternate
// same-host path.
if (
configuredBaseUrl &&
!isCanonicalConcentrateInferenceBaseUrl(configuredBaseUrl)
) {
return null
}
return {
OPENAI_BASE_URL: configuredBaseUrl || defaultBaseUrl,
OPENAI_MODEL:
normalizeProfileModel(
sanitizeProviderConfigValue(options.model, secretSource),
) ||
normalizeProfileModel(
sanitizeProviderConfigValue(processEnv.CONCENTRATE_MODEL, secretSource),
) ||
normalizeProfileModel(
sanitizeProviderConfigValue(processEnv.OPENAI_MODEL, secretSource),
) ||
defaultModel,
OPENAI_API_KEY: key,
CONCENTRATE_API_KEY: key,
CLAUDE_CODE_PROVIDER_ROUTE_ID: 'concentrate',
}
}
export function buildGeminiProfileEnv(options: {
model?: string | null
baseUrl?: string | null
@@ -1411,7 +1473,8 @@ function hasConcreteProviderSelection(
sanitizeApiKey(processEnv.APISMART_API_KEY) !== undefined ||
sanitizeApiKey(processEnv.FIREWORKS_API_KEY) !== undefined ||
sanitizeApiKey(processEnv.NEARAI_API_KEY) !== undefined ||
sanitizeApiKey(processEnv.LONGCAT_API_KEY) !== undefined
sanitizeApiKey(processEnv.LONGCAT_API_KEY) !== undefined ||
sanitizeApiKey(processEnv.CONCENTRATE_API_KEY) !== undefined
)
}
@@ -2080,14 +2143,25 @@ export async function buildLaunchEnv(options: {
effectiveOpenAIRouteId === 'apismart' &&
!!env.OPENAI_BASE_URL?.trim() &&
!isCanonicalApismartInferenceBaseUrl(env.OPENAI_BASE_URL)
const isNoncanonicalConcentrateLaunch =
effectiveOpenAIRouteId === 'concentrate' &&
!!env.OPENAI_BASE_URL?.trim() &&
!isCanonicalConcentrateInferenceBaseUrl(env.OPENAI_BASE_URL)
const isNoncanonicalDedicatedOpenAILaunch =
isNoncanonicalAimlapiLaunch || isNoncanonicalApismartLaunch
isNoncanonicalAimlapiLaunch || isNoncanonicalApismartLaunch || isNoncanonicalConcentrateLaunch
if (isNoncanonicalDedicatedOpenAILaunch) {
delete env.OPENAI_API_KEY
delete env.OPENAI_API_KEYS
const persistedCredential = resolveOpenAICredentialEnvSelection(persistedEnv)
if (persistedCredential) {
env[persistedCredential.envVar] = persistedCredential.value
// AIMLAPI and ApiSmart may retain a user-configured proxy credential in
// their persisted generic OpenAI field. Concentrate is different: its
// dedicated credential is never valid off the canonical endpoint, and
// older profiles could have stored that same secret under either generic
// alias. Do not resurrect it for a noncanonical Concentrate launch.
if (!isNoncanonicalConcentrateLaunch) {
const persistedCredential = resolveOpenAICredentialEnvSelection(persistedEnv)
if (persistedCredential) {
env[persistedCredential.envVar] = persistedCredential.value
}
}
// Custom authentication is a second credential channel, not just transport
// metadata: the OpenAI shim sends OPENAI_AUTH_HEADER_VALUE as the request
@@ -2115,6 +2189,7 @@ export async function buildLaunchEnv(options: {
for (const dedicatedKey of [
'ATLAS_CLOUD_API_KEY',
'APISMART_API_KEY',
'CONCENTRATE_API_KEY',
'NEARAI_API_KEY',
'FIREWORKS_API_KEY',
'LONGCAT_API_KEY',
@@ -2133,6 +2208,9 @@ export async function buildLaunchEnv(options: {
if (dedicatedKey === 'APISMART_API_KEY' && effectiveOpenAIRouteId !== 'apismart') {
continue
}
if (dedicatedKey === 'CONCENTRATE_API_KEY' && effectiveOpenAIRouteId !== 'concentrate') {
continue
}
if (dedicatedKey === 'NVIDIA_API_KEY' && effectiveOpenAIRouteId !== 'nvidia-nim') {
continue
}
@@ -2156,8 +2234,20 @@ export async function buildLaunchEnv(options: {
dedicatedKey === 'APISMART_API_KEY' &&
!!dedicatedBaseUrl &&
!isCanonicalApismartInferenceBaseUrl(dedicatedBaseUrl)
const withholdAmbientConcentrateKey =
dedicatedKey === 'CONCENTRATE_API_KEY' &&
!!dedicatedBaseUrl &&
!isCanonicalConcentrateInferenceBaseUrl(dedicatedBaseUrl)
const withholdAmbientDedicatedKey =
withholdAmbientAimlapiKey || withholdAmbientApismartKey
withholdAmbientAimlapiKey || withholdAmbientApismartKey || withholdAmbientConcentrateKey
// Unlike the generic proxy-compatible routes above, Concentrate's
// dedicated key is never valid outside its canonical inference endpoint.
// Do not preserve a legacy persisted key for a retargeted Concentrate
// profile: older versions could have serialized one before this boundary
// was enforced.
if (withholdAmbientConcentrateKey) {
continue
}
// AIMLAPI accepts generic OpenAI credentials, but ApiSmart is
// dedicatedCredentialsOnly. Never promote a shell OPENAI_API_KEY into the
// dedicated credential on relaunch.
@@ -2179,12 +2269,22 @@ export async function buildLaunchEnv(options: {
persistedOpenAICredential?.kind === 'usable'
? sanitizeApiKey(persistedOpenAICredential.value)
: undefined
const backfillLegacyConcentrateProfileKey =
dedicatedKey === 'CONCENTRATE_API_KEY' &&
effectiveOpenAIRouteId === 'concentrate' &&
persistedOpenAIRouteId === 'concentrate' &&
!!dedicatedBaseUrl &&
isCanonicalConcentrateInferenceBaseUrl(dedicatedBaseUrl) &&
persistedOpenAICredential?.kind === 'usable'
? sanitizeApiKey(persistedOpenAICredential.value)
: undefined
const dedicatedValue = withholdAmbientDedicatedKey
? sanitizeApiKey(persistedEnv[dedicatedKey])
: backfillDedicatedFromOpenAI ||
sanitizeApiKey(processEnv[dedicatedKey]) ||
sanitizeApiKey(persistedEnv[dedicatedKey]) ||
backfillLegacyApismartProfileKey
backfillLegacyApismartProfileKey ||
backfillLegacyConcentrateProfileKey
if (dedicatedValue) {
env[dedicatedKey] = dedicatedValue
}
@@ -2276,16 +2376,25 @@ export async function buildStartupEnvFromProfile(options?: {
// If startup already has a concrete provider selection, keep trusting it.
// This prevents legacy profiles or the fresh-install default from becoming
// a silent third precedence layer over explicit env/flags.
// A retained ApiSmart proxy profile carries route identity specifically to
// withhold ambient dedicated credentials from its noncanonical endpoint.
// Do not let an env-only key skip that guard; the persisted profile must be
// applied first so buildLaunchEnv can preserve the proxy boundary.
// Retained dedicated-provider proxy profiles carry route identity specifically
// to withhold ambient credentials from their noncanonical endpoint. Do not
// let an env-only key skip that guard; the persisted profile must be applied
// first so buildLaunchEnv can preserve the credential boundary.
const persistedApismartProxy =
persisted?.profile === 'openai' &&
persisted.env.CLAUDE_CODE_PROVIDER_ROUTE_ID === 'apismart' &&
!!persisted.env.OPENAI_BASE_URL?.trim() &&
!isCanonicalApismartInferenceBaseUrl(persisted.env.OPENAI_BASE_URL)
if (hasConcreteProviderSelection(processEnv) && !persistedApismartProxy) {
const persistedConcentrateProxy =
persisted?.profile === 'openai' &&
persisted.env.CLAUDE_CODE_PROVIDER_ROUTE_ID === 'concentrate' &&
!!persisted.env.OPENAI_BASE_URL?.trim() &&
!isCanonicalConcentrateInferenceBaseUrl(persisted.env.OPENAI_BASE_URL)
if (
hasConcreteProviderSelection(processEnv) &&
!persistedApismartProxy &&
!persistedConcentrateProxy
) {
return processEnv
}
+262 -1
View File
@@ -72,6 +72,9 @@ const RESTORED_KEYS = [
'ATLAS_CLOUD_API_KEY',
'APISMART_API_KEY',
'APISMART_MODEL',
'CONCENTRATE_API_KEY',
'CONCENTRATE_BASE_URL',
'CONCENTRATE_MODEL',
'CLINE_API_KEY',
'HICAP_API_KEY',
'CLOUDFLARE_API_TOKEN',
@@ -278,6 +281,17 @@ function buildApismartProfile(overrides: Partial<ProviderProfile> = {}): Provide
})
}
function buildConcentrateProfile(overrides: Partial<ProviderProfile> = {}): ProviderProfile {
return buildProfile({
provider: 'concentrate',
name: 'Concentrate',
baseUrl: 'https://api.concentrate.ai/v1',
model: 'deepseek-v4-flash-0731',
apiKey: 'concentrate-test-key',
...overrides,
})
}
function buildClinePassProfile(overrides: Partial<ProviderProfile> = {}): ProviderProfile {
return buildProfile({
provider: 'clinepass',
@@ -317,7 +331,7 @@ describe('applyProviderProfileToProcessEnv', () => {
)
expect(process.env.OPENAI_AZURE_STYLE).toBe('1')
})
}, 20_000)
test('openai profile clears competing gemini/github flags', async () => {
const { applyProviderProfileToProcessEnv } =
@@ -952,6 +966,200 @@ describe('applyProviderProfileToProcessEnv', () => {
expect(process.env.CLAUDE_CODE_PROVIDER_ROUTE_ID).toBe('apismart')
})
test('concentrate profile applies OpenAI-compatible env with CONCENTRATE_API_KEY mirror', async () => {
const { applyProviderProfileToProcessEnv } =
await importFreshProviderProfileModules()
process.env.CLAUDE_CODE_USE_GEMINI = '1'
applyProviderProfileToProcessEnv(buildConcentrateProfile())
const { getAPIProvider: getFreshAPIProvider } =
await importFreshProvidersModule()
expect(process.env.CLAUDE_CODE_USE_GEMINI).toBeUndefined()
expect(String(process.env.CLAUDE_CODE_USE_OPENAI)).toBe('1')
expect(process.env.OPENAI_BASE_URL).toBe('https://api.concentrate.ai/v1')
expect(process.env.OPENAI_MODEL).toBe('deepseek-v4-flash-0731')
expect(process.env.OPENAI_API_KEY).toBe('concentrate-test-key')
expect(process.env.CONCENTRATE_API_KEY).toBe('concentrate-test-key')
expect(process.env.CLAUDE_CODE_PROVIDER_ROUTE_ID).toBe('concentrate')
expect(getFreshAPIProvider()).toBe('openai')
})
test('generic OpenAI profile at the canonical Concentrate endpoint keeps its credential generic', async () => {
const { applyProviderProfileToProcessEnv } =
await importFreshProviderProfileModules()
const { getProviderValidationError } = await import(
`./providerValidation.js?ts=${Date.now()}-${Math.random()}`
)
applyProviderProfileToProcessEnv(
buildProfile({
provider: 'openai',
baseUrl: 'https://api.concentrate.ai/v1',
model: 'deepseek-v4-flash-0731',
apiKey: 'generic-concentrate-key',
}),
)
expect(process.env.OPENAI_API_KEY).toBe('generic-concentrate-key')
expect(process.env.CONCENTRATE_API_KEY).toBeUndefined()
expect(await getProviderValidationError(process.env)).toBeNull()
})
test('concentrate profile clears a stale route-specific model before applying its saved model', async () => {
const { applyProviderProfileToProcessEnv } =
await importFreshProviderProfileModules()
process.env.CONCENTRATE_MODEL = 'claude-sonnet-5'
applyProviderProfileToProcessEnv(buildConcentrateProfile())
expect(process.env.CONCENTRATE_MODEL).toBeUndefined()
expect(process.env.OPENAI_MODEL).toBe('deepseek-v4-flash-0731')
})
test('concentrate profile without a base URL retains its dedicated credential for the default route', async () => {
const { applyProviderProfileToProcessEnv } =
await importFreshProviderProfileModules()
applyProviderProfileToProcessEnv(
buildConcentrateProfile({ baseUrl: undefined }),
)
expect(process.env.OPENAI_BASE_URL).toBe('https://api.concentrate.ai/v1')
expect(process.env.OPENAI_API_KEY).toBe('concentrate-test-key')
expect(process.env.CONCENTRATE_API_KEY).toBe('concentrate-test-key')
})
test('retargeted Concentrate profile withholds its dedicated credential', async () => {
const { applyProviderProfileToProcessEnv } =
await importFreshProviderProfileModules()
applyProviderProfileToProcessEnv(
buildConcentrateProfile({ baseUrl: 'https://proxy.example/v1' }),
)
expect(process.env.OPENAI_BASE_URL).toBe('https://proxy.example/v1')
expect(process.env.OPENAI_API_KEY).toBeUndefined()
expect(process.env.CONCENTRATE_API_KEY).toBeUndefined()
expect(process.env.CLAUDE_CODE_PROVIDER_ROUTE_ID).toBe('concentrate')
})
test('retargeted Concentrate profiles retain generic proxy capabilities', async () => {
const { addProviderProfile, applyProviderProfileToProcessEnv } =
await importFreshProviderProfileModules()
const saved = addProviderProfile({
provider: 'concentrate',
name: 'Concentrate proxy',
baseUrl: 'https://proxy.example/v1',
model: 'proxy-model',
apiKey: 'concentrate-test-key',
apiFormat: 'responses',
authHeader: 'X-Proxy-Key',
authScheme: 'raw',
authHeaderValue: 'proxy-auth-value',
customHeaders: { 'X-Proxy-Trace': 'enabled' },
})
expect(saved).toMatchObject({
apiFormat: 'responses',
authHeader: 'X-Proxy-Key',
authScheme: 'raw',
authHeaderValue: 'proxy-auth-value',
customHeaders: { 'X-Proxy-Trace': 'enabled' },
})
applyProviderProfileToProcessEnv(saved!)
expect(process.env.OPENAI_BASE_URL).toBe('https://proxy.example/v1')
expect(process.env.OPENAI_API_FORMAT).toBe('responses')
expect(process.env.OPENAI_AUTH_HEADER).toBe('X-Proxy-Key')
expect(process.env.OPENAI_AUTH_SCHEME).toBe('raw')
expect(process.env.OPENAI_AUTH_HEADER_VALUE).toBe('proxy-auth-value')
expect(process.env.ANTHROPIC_CUSTOM_HEADERS).toBe(
'X-Proxy-Trace: enabled',
)
expect(process.env.OPENAI_API_KEY).toBeUndefined()
expect(process.env.CONCENTRATE_API_KEY).toBeUndefined()
})
test('keyless Concentrate profile resolves CONCENTRATE_API_KEY without persisting it', async () => {
const { applyProviderProfileToProcessEnv } =
await importFreshProviderProfileModules()
process.env.CONCENTRATE_API_KEY = 'ambient-concentrate-key'
applyProviderProfileToProcessEnv(
buildConcentrateProfile({
apiKey: undefined,
baseUrl: 'https://api.concentrate.ai/v1',
}),
)
expect(process.env.OPENAI_API_KEY).toBe('ambient-concentrate-key')
expect(process.env.CONCENTRATE_API_KEY).toBe('ambient-concentrate-key')
expect(process.env.CLAUDE_CODE_PROVIDER_ROUTE_ID).toBe('concentrate')
}, 20_000)
test('keyless canonical Concentrate profile never promotes a generic OpenAI key', async () => {
const { applyProviderProfileToProcessEnv } =
await importFreshProviderProfileModules()
process.env.OPENAI_API_KEY = 'generic-openai-key'
applyProviderProfileToProcessEnv(
buildConcentrateProfile({
apiKey: undefined,
baseUrl: 'https://api.concentrate.ai/v1',
}),
)
expect(process.env.OPENAI_API_KEY).toBeUndefined()
expect(process.env.CONCENTRATE_API_KEY).toBeUndefined()
expect(process.env.CLAUDE_CODE_PROVIDER_ROUTE_ID).toBe('concentrate')
}, 20_000)
test('non-canonical Concentrate host path withholds the dedicated credential', async () => {
const { applyProviderProfileToProcessEnv } =
await importFreshProviderProfileModules()
applyProviderProfileToProcessEnv(
buildConcentrateProfile({
baseUrl: 'https://api.concentrate.ai/staging/v1',
}),
)
expect(process.env.OPENAI_BASE_URL).toBe(
'https://api.concentrate.ai/staging/v1',
)
expect(process.env.OPENAI_API_KEY).toBeUndefined()
expect(process.env.CONCENTRATE_API_KEY).toBeUndefined()
expect(process.env.CLAUDE_CODE_PROVIDER_ROUTE_ID).toBe('concentrate')
})
test.each(['SUA_CHAVE', 'sua_chave', 'null', 'undefined', ' NULL '])(
'addProviderProfile drops placeholder Concentrate credential %s',
async placeholder => {
const { addProviderProfile, getProviderProfiles } =
await importFreshProviderProfileModules()
saveMockGlobalConfig(current => ({
...current,
providerProfiles: [],
activeProviderProfileId: undefined,
}))
const saved = addProviderProfile({
provider: 'concentrate',
name: 'Concentrate',
baseUrl: 'https://api.concentrate.ai/v1',
model: 'deepseek-v4-flash-0731',
apiKey: placeholder,
})
expect(saved?.apiKey).toBeUndefined()
expect(getProviderProfiles()[0]?.apiKey).toBeUndefined()
},
)
test.each(['SUA_CHAVE', 'sua_chave', 'null', 'undefined', ' NULL '])(
'addProviderProfile drops placeholder ApiSmart credential %s',
async placeholder => {
@@ -3354,6 +3562,59 @@ describe('setActiveProviderProfile', () => {
}
})
test('retargeted Concentrate profiles keep route identity but persist without their dedicated credential', async () => {
const tempDir = mkdtempSync(join(tmpdir(), 'openclaude-provider-'))
const configDir = mkdtempSync(join(tmpdir(), 'openclaude-provider-config-'))
process.chdir(tempDir)
process.env.CLAUDE_CONFIG_DIR = configDir
try {
const { setActiveProviderProfile } =
await importFreshProviderProfileModules()
const concentrateProfile = buildConcentrateProfile({
id: 'concentrate_proxy',
baseUrl: 'https://api.concentrate.ai/staging/v1',
})
saveMockGlobalConfig(current => ({
...current,
providerProfiles: [concentrateProfile],
}))
const result = setActiveProviderProfile('concentrate_proxy', { configDir })
const persisted = JSON.parse(
readFileSync(join(configDir, '.openclaude-profile.json'), 'utf8'),
)
expect(result?.id).toBe('concentrate_proxy')
expect(persisted.profile).toBe('openai')
expect(persisted.env).toEqual({
CLAUDE_CODE_PROVIDER_ROUTE_ID: 'concentrate',
OPENAI_BASE_URL: 'https://api.concentrate.ai/staging/v1',
OPENAI_MODEL: 'deepseek-v4-flash-0731',
})
const { buildStartupEnvFromProfile } = await import(
`./providerProfile.js?ts=${Date.now()}-${Math.random()}`
)
const startupEnv = await buildStartupEnvFromProfile({
persisted,
processEnv: {
CONCENTRATE_API_KEY: 'ambient-concentrate-key',
OPENAI_API_KEY: 'ambient-concentrate-key',
},
})
expect(startupEnv.CLAUDE_CODE_PROVIDER_ROUTE_ID).toBe('concentrate')
expect(startupEnv.CONCENTRATE_API_KEY).toBeUndefined()
expect(startupEnv.OPENAI_API_KEY).toBeUndefined()
} finally {
process.chdir(originalCwd)
rmSync(tempDir, { recursive: true, force: true })
rmSync(configDir, { recursive: true, force: true })
}
})
test('persists Xiaomi MiMo profiles using a legacy-compatible openai startup profile', async () => {
const tempDir = mkdtempSync(join(tmpdir(), 'openclaude-provider-'))
const configDir = mkdtempSync(join(tmpdir(), 'openclaude-provider-config-'))
+100 -15
View File
@@ -18,6 +18,7 @@ import {
createProfileFile,
saveProfileFile,
buildBedrockProfileEnv,
buildConcentrateProfileEnv,
buildGeminiProfileEnv,
buildGithubProfileEnv,
buildMiniMaxProfileEnv,
@@ -55,6 +56,7 @@ import {
isCloudflareBaseUrl,
isClinePassBaseUrl,
isCanonicalApismartInferenceBaseUrl,
isCanonicalConcentrateInferenceBaseUrl,
isFireworksBaseUrl,
isLongcatBaseUrl,
isNearaiBaseUrl,
@@ -161,6 +163,18 @@ function isApismartProfile(profile: ProviderProfile): boolean {
return !baseUrl || isCanonicalApismartInferenceBaseUrl(baseUrl)
}
function isConcentrateProfile(profile: ProviderProfile): boolean {
const { route } = resolveProfileCompatibility(profile.provider)
if (route.routeId !== 'concentrate') {
return false
}
const baseUrl = profile.baseUrl?.trim()
// Missing base URL resolves to the Concentrate default, which is canonical.
// Only the documented `/v1` inference URL may carry the dedicated key —
// host-only or path-suffixed Concentrate URLs are treated as retargeted.
return !baseUrl || isCanonicalConcentrateInferenceBaseUrl(baseUrl)
}
function deriveGithubEnterpriseUrl(baseUrl: string | undefined): string | undefined {
if (!baseUrl?.trim()) return undefined
try {
@@ -239,15 +253,19 @@ function resolveProfileCapabilityRouteId(
return routeIdFromBaseUrl
}
// Cloudflare and LongCat profiles retargeted away from their dedicated
// endpoints run generically at runtime. Mirror that boundary here so
// capability-driven surfaces are not stripped based on stale route ids.
// Dedicated-route profiles retargeted away from their documented endpoints
// run generically at runtime. Mirror that boundary here so capability-driven
// surfaces are not stripped based on stale route ids.
if (
(providerRouteId === 'cloudflare' || providerRouteId === 'longcat') &&
(providerRouteId === 'cloudflare' ||
providerRouteId === 'longcat' ||
providerRouteId === 'concentrate') &&
baseUrl &&
!(providerRouteId === 'cloudflare'
? isCloudflareBaseUrl(baseUrl)
: isLongcatBaseUrl(baseUrl))
: providerRouteId === 'longcat'
? isLongcatBaseUrl(baseUrl)
: isCanonicalConcentrateInferenceBaseUrl(baseUrl))
) {
return 'custom'
}
@@ -972,7 +990,9 @@ export function applyProviderProfileToProcessEnv(
? normalizeXiaomiMimoBaseUrl(profile.baseUrl) ?? profile.baseUrl
: route.routeId === 'apismart' && !profile.baseUrl?.trim()
? getRouteDefaultBaseUrl('apismart') ?? profile.baseUrl
: profile.baseUrl
: route.routeId === 'concentrate' && !profile.baseUrl?.trim()
? getRouteDefaultBaseUrl('concentrate') ?? profile.baseUrl
: profile.baseUrl
const openAIProfileEnv: ProfileEnv = {
OPENAI_BASE_URL: normalizedProfileBaseUrl,
OPENAI_MODEL: primaryModel,
@@ -1001,7 +1021,13 @@ export function applyProviderProfileToProcessEnv(
const withholdRetargetedApismartCredential =
route.routeId === 'apismart' && !isApismartProfile(profile)
if (profile.apiKey && !withholdRetargetedApismartCredential) {
const withholdRetargetedConcentrateCredential =
route.routeId === 'concentrate' && !isConcentrateProfile(profile)
if (
profile.apiKey &&
!withholdRetargetedApismartCredential &&
!withholdRetargetedConcentrateCredential
) {
openAIProfileEnv.OPENAI_API_KEY = profile.apiKey
if (route.vendorId === 'minimax' || normalizedProfileBaseUrl.toLowerCase().includes('minimax')) {
openAIProfileEnv.MINIMAX_API_KEY = profile.apiKey
@@ -1038,6 +1064,9 @@ export function applyProviderProfileToProcessEnv(
if (isApismartProfile(profile)) {
openAIProfileEnv.APISMART_API_KEY = profile.apiKey
}
if (isConcentrateProfile(profile)) {
openAIProfileEnv.CONCENTRATE_API_KEY = profile.apiKey
}
if (isClinePassProfile(profile)) {
openAIProfileEnv.CLINE_API_KEY = profile.apiKey
}
@@ -1094,10 +1123,29 @@ export function applyProviderProfileToProcessEnv(
// must not receive the ambient key.
if (isApismartProfile(profile)) {
const ambientApismartKey = sanitizeApiKey(process.env.APISMART_API_KEY)
openAIProfileEnv.OPENAI_API_KEY =
openAIProfileEnv.OPENAI_API_KEY ?? ambientApismartKey
openAIProfileEnv.APISMART_API_KEY =
openAIProfileEnv.APISMART_API_KEY ?? ambientApismartKey
if (ambientApismartKey) {
openAIProfileEnv.OPENAI_API_KEY =
openAIProfileEnv.OPENAI_API_KEY ?? ambientApismartKey
openAIProfileEnv.APISMART_API_KEY =
openAIProfileEnv.APISMART_API_KEY ?? ambientApismartKey
}
}
}
// Stamp dedicated Concentrate profile identity and mirror its credential so
// the saved profile relaunches authenticated.
if (route.routeId === 'concentrate') {
openAIProfileEnv.CLAUDE_CODE_PROVIDER_ROUTE_ID = 'concentrate'
// Keyless canonical Concentrate profiles may resolve the ambient dedicated
// credential the same way ApiSmart does.
if (isConcentrateProfile(profile) && !profile.apiKey) {
const ambientConcentrateKey = sanitizeApiKey(
process.env.CONCENTRATE_API_KEY,
)
if (ambientConcentrateKey) {
openAIProfileEnv.OPENAI_API_KEY =
openAIProfileEnv.OPENAI_API_KEY ?? ambientConcentrateKey
openAIProfileEnv.CONCENTRATE_API_KEY = ambientConcentrateKey
}
}
}
if (route.gatewayId === 'nvidia-nim') {
@@ -1381,14 +1429,23 @@ function buildOpenAICompatibleStartupEnv(
if (isCodexBaseUrl(activeProfile.baseUrl)) {
return null
}
const activeProfileRouteId = resolveProfileRoute(activeProfile.provider).routeId
const withholdRetargetedApismartCredential =
resolveProfileRoute(activeProfile.provider).routeId === 'apismart' &&
activeProfileRouteId === 'apismart' &&
!isApismartProfile(activeProfile)
const withholdRetargetedConcentrateCredential =
activeProfileRouteId === 'concentrate' &&
!isConcentrateProfile(activeProfile)
const isAimlapiProfile =
activeProfile.provider === 'aimlapi' ||
resolveRouteIdFromBaseUrl(activeProfile.baseUrl) === 'aimlapi'
const isConcentrateProfileFlag = isConcentrateProfile(activeProfile)
if (activeProfile.apiKey && !withholdRetargetedApismartCredential) {
if (
activeProfile.apiKey &&
!withholdRetargetedApismartCredential &&
!withholdRetargetedConcentrateCredential
) {
const strictEnv = buildOpenAIProfileEnv({
goal: 'balanced',
model: activeProfile.model,
@@ -1416,6 +1473,9 @@ function buildOpenAICompatibleStartupEnv(
if (isApismartProfile(activeProfile)) {
strictEnv.APISMART_API_KEY = activeProfile.apiKey
}
if (isConcentrateProfileFlag) {
strictEnv.CONCENTRATE_API_KEY = activeProfile.apiKey
}
if (isClinePassProfile(activeProfile)) {
strictEnv.CLINE_API_KEY = activeProfile.apiKey
}
@@ -1465,10 +1525,19 @@ function buildOpenAICompatibleStartupEnv(
// Preserve ApiSmart identity on retargeted/proxy startup envs so relaunch
// withholding can refuse ambient dedicated credentials. Canonical profiles
// already stamp this via buildApismartProfileEnv.
if (resolveProfileRoute(activeProfile.provider).routeId === 'apismart') {
if (activeProfileRouteId === 'apismart') {
env.CLAUDE_CODE_PROVIDER_ROUTE_ID = 'apismart'
}
if (activeProfile.apiKey && !withholdRetargetedApismartCredential) {
// Preserve Concentrate identity for retargeted profiles too, so a later
// launch can apply the same dedicated-credential boundary.
if (activeProfileRouteId === 'concentrate') {
env.CLAUDE_CODE_PROVIDER_ROUTE_ID = 'concentrate'
}
if (
activeProfile.apiKey &&
!withholdRetargetedApismartCredential &&
!withholdRetargetedConcentrateCredential
) {
env.OPENAI_API_KEY = activeProfile.apiKey
if (activeProfile.baseUrl?.toLowerCase().includes('bankr')) {
env.BNKR_API_KEY = activeProfile.apiKey
@@ -1494,6 +1563,9 @@ function buildOpenAICompatibleStartupEnv(
if (isApismartProfile(activeProfile)) {
env.APISMART_API_KEY = activeProfile.apiKey
}
if (isConcentrateProfileFlag) {
env.CONCENTRATE_API_KEY = activeProfile.apiKey
}
if (isClinePassProfile(activeProfile)) {
env.CLINE_API_KEY = activeProfile.apiKey
}
@@ -1696,6 +1768,19 @@ function buildStartupProfileFromActiveProfile(
: null
}
if (route.routeId === 'concentrate' && isConcentrateProfile(activeProfile)) {
const env =
buildConcentrateProfileEnv({
model: getPrimaryModel(activeProfile.model),
baseUrl: activeProfile.baseUrl,
apiKey: activeProfile.apiKey,
processEnv: process.env,
}) ?? null
return env
? { profile: 'openai', env: applySupportedProfileCustomHeaders(activeProfile, env) }
: null
}
if (route.vendorId === 'nearai') {
const env = buildOpenAICompatibleStartupEnv(activeProfile)
return env ? { profile: 'openai', env } : null
+77
View File
@@ -33,6 +33,9 @@ const ENV_KEYS = [
'MINIMAX_API_KEY',
'LONGCAT_API_KEY',
'APISMART_API_KEY',
'CONCENTRATE_API_KEY',
'CONCENTRATE_BASE_URL',
'CONCENTRATE_MODEL',
'NVIDIA_API_KEY',
'NVIDIA_NIM',
'BNKR_API_KEY',
@@ -211,6 +214,80 @@ test('noncanonical ApiSmart paths do not validate a dedicated credential', async
)
})
test('noncanonical Concentrate host paths fall back to generic OpenAI validation', async () => {
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.OPENAI_BASE_URL = 'https://api.concentrate.ai/staging/v1'
process.env.OPENAI_API_KEY = 'generic-proxy-key'
delete process.env.CONCENTRATE_API_KEY
delete process.env.OPENAI_API_KEYS
await expect(getProviderValidationError(process.env)).resolves.toBeNull()
})
test('canonical Concentrate base supports the documented generic OpenAI credential', async () => {
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.OPENAI_BASE_URL = 'https://api.concentrate.ai/v1'
process.env.OPENAI_API_KEY = 'generic-concentrate-key'
delete process.env.CONCENTRATE_API_KEY
await expect(getProviderValidationError(process.env)).resolves.toBeNull()
})
test('noncanonical same-host base rejects a selected CONCENTRATE_API_KEY route', async () => {
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.OPENAI_BASE_URL = 'https://api.concentrate.ai/staging/v1'
process.env.CONCENTRATE_API_KEY = 'concentrate-key'
delete process.env.OPENAI_API_KEY
delete process.env.OPENAI_API_KEYS
await expect(getProviderValidationError(process.env)).resolves.toBe(
'Concentrate credentials require the canonical https://api.concentrate.ai/v1 endpoint.',
)
})
test('noncanonical CONCENTRATE_BASE_URL is rejected instead of silently withholding its key', async () => {
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.CONCENTRATE_BASE_URL = 'https://api.concentrate.ai/staging/v1'
process.env.CONCENTRATE_API_KEY = 'concentrate-key'
delete process.env.OPENAI_API_KEY
delete process.env.OPENAI_API_KEYS
await expect(getProviderValidationError(process.env)).resolves.toBe(
'Concentrate credentials require the canonical https://api.concentrate.ai/v1 endpoint.',
)
})
test('key-only noncanonical Concentrate setup validates before OpenAI mode is enabled', async () => {
process.env.CONCENTRATE_BASE_URL = 'https://api.concentrate.ai/staging/v1'
process.env.CONCENTRATE_API_KEY = 'concentrate-key'
delete process.env.OPENAI_API_KEY
delete process.env.OPENAI_API_KEYS
await expect(getProviderValidationError(process.env)).resolves.toBe(
'Concentrate credentials require the canonical https://api.concentrate.ai/v1 endpoint.',
)
})
test('Concentrate key-only setup validates before client defaults are applied', async () => {
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.CONCENTRATE_API_KEY = 'concentrate-key'
await expect(getProviderValidationError(process.env)).resolves.toBeNull()
})
test.each(['SUA_CHAVE', 'sua_chave', 'null', 'undefined', ' NULL '])(
'Concentrate validation rejects placeholder CONCENTRATE_API_KEY %s',
async placeholder => {
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.OPENAI_BASE_URL = 'https://api.concentrate.ai/v1'
process.env.CONCENTRATE_API_KEY = placeholder
await expect(getProviderValidationError(process.env)).resolves.toBe(
'Concentrate auth is required. Set CONCENTRATE_API_KEY or OPENAI_API_KEY.',
)
},
)
test.each(['SUA_CHAVE', 'sua_chave', 'null', 'undefined', ' NULL '])(
'ApiSmart validation rejects placeholder APISMART_API_KEY %s',
async placeholder => {
+29 -2
View File
@@ -16,6 +16,7 @@ import {
getRouteDescriptor,
getRouteDefaultModel,
isCanonicalApismartInferenceBaseUrl,
isCanonicalConcentrateInferenceBaseUrl,
isCloudflareBaseUrl,
isLongcatBaseUrl,
matchHostnameAgainstRouteHosts,
@@ -139,7 +140,8 @@ function hasUsableCredentialEnvValue(
envVar === 'OPENAI_API_KEYS' ||
envVar === 'OPENAI_API_KEY' ||
envVar === 'AIMLAPI_API_KEY' ||
envVar === 'APISMART_API_KEY'
envVar === 'APISMART_API_KEY' ||
envVar === 'CONCENTRATE_API_KEY'
) {
return hasUsableOpenAICredential(value)
}
@@ -261,6 +263,14 @@ function getRuntimeValidationTarget(
return enabledTarget
}
// The documented CONCENTRATE_API_KEY-only setup is routed before the client
// applies its default base URL. Select its descriptor directly so startup
// validates the dedicated credential, including a noncanonical dedicated
// base URL, instead of returning early for an unset OpenAI mode.
if (resolveActiveRouteIdFromEnv(env) === 'concentrate') {
return validationTargets.find(target => target.descriptor.id === 'concentrate')
}
if (!useOpenAI) {
return undefined
}
@@ -286,7 +296,9 @@ function getRuntimeValidationTarget(
(target.descriptor.id === 'longcat' &&
!isLongcatBaseUrl(request.baseUrl)) ||
(target.descriptor.id === 'apismart' &&
!isCanonicalApismartInferenceBaseUrl(request.baseUrl)))
!isCanonicalApismartInferenceBaseUrl(request.baseUrl)) ||
(target.descriptor.id === 'concentrate' &&
!isCanonicalConcentrateInferenceBaseUrl(request.baseUrl)))
) {
return false
}
@@ -389,6 +401,21 @@ async function getDescriptorValidationError(
return null
}
// An explicit Concentrate credential carries the dedicated contract. A
// same-host proxy with only generic OpenAI variables is not selected as this
// route, but once Concentrate is selected its base must be canonical.
const concentrateBaseUrl =
env.CONCENTRATE_BASE_URL?.trim() ||
env.OPENAI_BASE_URL?.trim() ||
env.OPENAI_API_BASE?.trim()
if (
target.descriptor.id === 'concentrate' &&
concentrateBaseUrl &&
!isCanonicalConcentrateInferenceBaseUrl(concentrateBaseUrl)
) {
return 'Concentrate credentials require the canonical https://api.concentrate.ai/v1 endpoint.'
}
switch (validation.kind) {
case 'credential-env':
return getCredentialEnvValidationError(validation, env, options.request)