feat: add OpenAI-compatible provider shim — use any LLM with Claude Code
Adds a new 'openai' API provider that translates Anthropic SDK calls to OpenAI chat completions format, enabling Claude Code's full tool system (bash, file read/write/edit, grep, glob, agents) with any OpenAI-compatible model: GPT-4o, DeepSeek, Gemini, Llama, Ollama, OpenRouter, and 200+ more. Set CLAUDE_CODE_USE_OPENAI=1, OPENAI_API_KEY, and OPENAI_MODEL to use. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d2542c9a62
commit
619b5fb603
@@ -1728,12 +1728,13 @@ export function getSubscriptionName(): string {
|
||||
}
|
||||
}
|
||||
|
||||
/** Check if using third-party services (Bedrock or Vertex or Foundry) */
|
||||
/** Check if using third-party services (Bedrock or Vertex or Foundry or OpenAI-compatible) */
|
||||
export function isUsing3PServices(): boolean {
|
||||
return !!(
|
||||
isEnvTruthy(process.env.CLAUDE_CODE_USE_BEDROCK) ||
|
||||
isEnvTruthy(process.env.CLAUDE_CODE_USE_VERTEX) ||
|
||||
isEnvTruthy(process.env.CLAUDE_CODE_USE_FOUNDRY)
|
||||
isEnvTruthy(process.env.CLAUDE_CODE_USE_FOUNDRY) ||
|
||||
isEnvTruthy(process.env.CLAUDE_CODE_USE_OPENAI)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,17 @@ import type { APIProvider } from './providers.js'
|
||||
|
||||
export type ModelConfig = Record<APIProvider, ModelName>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// OpenAI-compatible model mappings
|
||||
// Maps Claude model tiers to sensible defaults for popular providers.
|
||||
// Override with OPENAI_MODEL, ANTHROPIC_MODEL, or settings.model
|
||||
// ---------------------------------------------------------------------------
|
||||
export const OPENAI_MODEL_DEFAULTS = {
|
||||
opus: 'gpt-4o', // best reasoning
|
||||
sonnet: 'gpt-4o-mini', // balanced
|
||||
haiku: 'gpt-4o-mini', // fast & cheap
|
||||
} as const
|
||||
|
||||
// @[MODEL LAUNCH]: Add a new CLAUDE_*_CONFIG constant here. Double check the correct model strings
|
||||
// here since the pattern may change.
|
||||
|
||||
@@ -11,6 +22,7 @@ export const CLAUDE_3_7_SONNET_CONFIG = {
|
||||
bedrock: 'us.anthropic.claude-3-7-sonnet-20250219-v1:0',
|
||||
vertex: 'claude-3-7-sonnet@20250219',
|
||||
foundry: 'claude-3-7-sonnet',
|
||||
openai: 'gpt-4o-mini',
|
||||
} as const satisfies ModelConfig
|
||||
|
||||
export const CLAUDE_3_5_V2_SONNET_CONFIG = {
|
||||
@@ -18,6 +30,7 @@ export const CLAUDE_3_5_V2_SONNET_CONFIG = {
|
||||
bedrock: 'anthropic.claude-3-5-sonnet-20241022-v2:0',
|
||||
vertex: 'claude-3-5-sonnet-v2@20241022',
|
||||
foundry: 'claude-3-5-sonnet',
|
||||
openai: 'gpt-4o-mini',
|
||||
} as const satisfies ModelConfig
|
||||
|
||||
export const CLAUDE_3_5_HAIKU_CONFIG = {
|
||||
@@ -25,6 +38,7 @@ export const CLAUDE_3_5_HAIKU_CONFIG = {
|
||||
bedrock: 'us.anthropic.claude-3-5-haiku-20241022-v1:0',
|
||||
vertex: 'claude-3-5-haiku@20241022',
|
||||
foundry: 'claude-3-5-haiku',
|
||||
openai: 'gpt-4o-mini',
|
||||
} as const satisfies ModelConfig
|
||||
|
||||
export const CLAUDE_HAIKU_4_5_CONFIG = {
|
||||
@@ -32,6 +46,7 @@ export const CLAUDE_HAIKU_4_5_CONFIG = {
|
||||
bedrock: 'us.anthropic.claude-haiku-4-5-20251001-v1:0',
|
||||
vertex: 'claude-haiku-4-5@20251001',
|
||||
foundry: 'claude-haiku-4-5',
|
||||
openai: 'gpt-4o-mini',
|
||||
} as const satisfies ModelConfig
|
||||
|
||||
export const CLAUDE_SONNET_4_CONFIG = {
|
||||
@@ -39,6 +54,7 @@ export const CLAUDE_SONNET_4_CONFIG = {
|
||||
bedrock: 'us.anthropic.claude-sonnet-4-20250514-v1:0',
|
||||
vertex: 'claude-sonnet-4@20250514',
|
||||
foundry: 'claude-sonnet-4',
|
||||
openai: 'gpt-4o-mini',
|
||||
} as const satisfies ModelConfig
|
||||
|
||||
export const CLAUDE_SONNET_4_5_CONFIG = {
|
||||
@@ -46,6 +62,7 @@ export const CLAUDE_SONNET_4_5_CONFIG = {
|
||||
bedrock: 'us.anthropic.claude-sonnet-4-5-20250929-v1:0',
|
||||
vertex: 'claude-sonnet-4-5@20250929',
|
||||
foundry: 'claude-sonnet-4-5',
|
||||
openai: 'gpt-4o',
|
||||
} as const satisfies ModelConfig
|
||||
|
||||
export const CLAUDE_OPUS_4_CONFIG = {
|
||||
@@ -53,6 +70,7 @@ export const CLAUDE_OPUS_4_CONFIG = {
|
||||
bedrock: 'us.anthropic.claude-opus-4-20250514-v1:0',
|
||||
vertex: 'claude-opus-4@20250514',
|
||||
foundry: 'claude-opus-4',
|
||||
openai: 'gpt-4o',
|
||||
} as const satisfies ModelConfig
|
||||
|
||||
export const CLAUDE_OPUS_4_1_CONFIG = {
|
||||
@@ -60,6 +78,7 @@ export const CLAUDE_OPUS_4_1_CONFIG = {
|
||||
bedrock: 'us.anthropic.claude-opus-4-1-20250805-v1:0',
|
||||
vertex: 'claude-opus-4-1@20250805',
|
||||
foundry: 'claude-opus-4-1',
|
||||
openai: 'gpt-4o',
|
||||
} as const satisfies ModelConfig
|
||||
|
||||
export const CLAUDE_OPUS_4_5_CONFIG = {
|
||||
@@ -67,6 +86,7 @@ export const CLAUDE_OPUS_4_5_CONFIG = {
|
||||
bedrock: 'us.anthropic.claude-opus-4-5-20251101-v1:0',
|
||||
vertex: 'claude-opus-4-5@20251101',
|
||||
foundry: 'claude-opus-4-5',
|
||||
openai: 'gpt-4o',
|
||||
} as const satisfies ModelConfig
|
||||
|
||||
export const CLAUDE_OPUS_4_6_CONFIG = {
|
||||
@@ -74,6 +94,7 @@ export const CLAUDE_OPUS_4_6_CONFIG = {
|
||||
bedrock: 'us.anthropic.claude-opus-4-6-v1',
|
||||
vertex: 'claude-opus-4-6',
|
||||
foundry: 'claude-opus-4-6',
|
||||
openai: 'gpt-4o',
|
||||
} as const satisfies ModelConfig
|
||||
|
||||
export const CLAUDE_SONNET_4_6_CONFIG = {
|
||||
@@ -81,6 +102,7 @@ export const CLAUDE_SONNET_4_6_CONFIG = {
|
||||
bedrock: 'us.anthropic.claude-sonnet-4-6',
|
||||
vertex: 'claude-sonnet-4-6',
|
||||
foundry: 'claude-sonnet-4-6',
|
||||
openai: 'gpt-4o',
|
||||
} as const satisfies ModelConfig
|
||||
|
||||
// @[MODEL LAUNCH]: Register the new config here.
|
||||
|
||||
@@ -34,7 +34,12 @@ export type ModelName = string
|
||||
export type ModelSetting = ModelName | ModelAlias | null
|
||||
|
||||
export function getSmallFastModel(): ModelName {
|
||||
return process.env.ANTHROPIC_SMALL_FAST_MODEL || getDefaultHaikuModel()
|
||||
if (process.env.ANTHROPIC_SMALL_FAST_MODEL) return process.env.ANTHROPIC_SMALL_FAST_MODEL
|
||||
// For OpenAI provider, use OPENAI_MODEL or a sensible default
|
||||
if (getAPIProvider() === 'openai') {
|
||||
return process.env.OPENAI_MODEL || 'gpt-4o-mini'
|
||||
}
|
||||
return getDefaultHaikuModel()
|
||||
}
|
||||
|
||||
export function isNonCustomOpusModel(model: ModelName): boolean {
|
||||
@@ -66,7 +71,7 @@ export function getUserSpecifiedModelSetting(): ModelSetting | undefined {
|
||||
specifiedModel = modelOverride
|
||||
} else {
|
||||
const settings = getSettings_DEPRECATED() || {}
|
||||
specifiedModel = process.env.ANTHROPIC_MODEL || settings.model || undefined
|
||||
specifiedModel = process.env.ANTHROPIC_MODEL || process.env.OPENAI_MODEL || settings.model || undefined
|
||||
}
|
||||
|
||||
// Ignore the user-specified model if it's not in the availableModels allowlist.
|
||||
@@ -106,6 +111,10 @@ export function getDefaultOpusModel(): ModelName {
|
||||
if (process.env.ANTHROPIC_DEFAULT_OPUS_MODEL) {
|
||||
return process.env.ANTHROPIC_DEFAULT_OPUS_MODEL
|
||||
}
|
||||
// OpenAI provider: use user-specified model or default
|
||||
if (getAPIProvider() === 'openai') {
|
||||
return process.env.OPENAI_MODEL || 'gpt-4o'
|
||||
}
|
||||
// 3P providers (Bedrock, Vertex, Foundry) — kept as a separate branch
|
||||
// even when values match, since 3P availability lags firstParty and
|
||||
// these will diverge again at the next model launch.
|
||||
@@ -120,6 +129,10 @@ export function getDefaultSonnetModel(): ModelName {
|
||||
if (process.env.ANTHROPIC_DEFAULT_SONNET_MODEL) {
|
||||
return process.env.ANTHROPIC_DEFAULT_SONNET_MODEL
|
||||
}
|
||||
// OpenAI provider
|
||||
if (getAPIProvider() === 'openai') {
|
||||
return process.env.OPENAI_MODEL || 'gpt-4o'
|
||||
}
|
||||
// Default to Sonnet 4.5 for 3P since they may not have 4.6 yet
|
||||
if (getAPIProvider() !== 'firstParty') {
|
||||
return getModelStrings().sonnet45
|
||||
@@ -132,6 +145,10 @@ export function getDefaultHaikuModel(): ModelName {
|
||||
if (process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL) {
|
||||
return process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL
|
||||
}
|
||||
// OpenAI provider
|
||||
if (getAPIProvider() === 'openai') {
|
||||
return process.env.OPENAI_MODEL || 'gpt-4o-mini'
|
||||
}
|
||||
|
||||
// Haiku 4.5 is available on all platforms (first-party, Foundry, Bedrock, Vertex)
|
||||
return getModelStrings().haiku45
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import type { AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS } from '../../services/analytics/index.js'
|
||||
import { isEnvTruthy } from '../envUtils.js'
|
||||
|
||||
export type APIProvider = 'firstParty' | 'bedrock' | 'vertex' | 'foundry'
|
||||
export type APIProvider = 'firstParty' | 'bedrock' | 'vertex' | 'foundry' | 'openai'
|
||||
|
||||
export function getAPIProvider(): APIProvider {
|
||||
return isEnvTruthy(process.env.CLAUDE_CODE_USE_BEDROCK)
|
||||
? 'bedrock'
|
||||
: isEnvTruthy(process.env.CLAUDE_CODE_USE_VERTEX)
|
||||
? 'vertex'
|
||||
: isEnvTruthy(process.env.CLAUDE_CODE_USE_FOUNDRY)
|
||||
? 'foundry'
|
||||
: 'firstParty'
|
||||
return isEnvTruthy(process.env.CLAUDE_CODE_USE_OPENAI)
|
||||
? 'openai'
|
||||
: isEnvTruthy(process.env.CLAUDE_CODE_USE_BEDROCK)
|
||||
? 'bedrock'
|
||||
: isEnvTruthy(process.env.CLAUDE_CODE_USE_VERTEX)
|
||||
? 'vertex'
|
||||
: isEnvTruthy(process.env.CLAUDE_CODE_USE_FOUNDRY)
|
||||
? 'foundry'
|
||||
: 'firstParty'
|
||||
}
|
||||
|
||||
export function getAPIProviderForStatsig(): AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS {
|
||||
|
||||
Reference in New Issue
Block a user