feat: add xAI as official provider (#865)
* feat: add xAI as official provider - Add xAI preset to ProviderManager (alphabetical order) - Add xAI provider detection via XAI_API_KEY - Add xAI startup screen heuristic (x.ai base URL or grok model) - Add xAI status display properties - Add grok-4 and grok-3 context windows - Add xAI model fallbacks across all tiers - Fix JSDoc priority order in providerAutoDetect Co-Authored-By: Claude Opus 4.6 <noreply@openclaude.dev> * fix(xai): persist relaunch classification for xAI profiles Addresses reviewer feedback on feat/xai-official-provider: - isProcessEnvAlignedWithProfile now validates XAI_API_KEY for x.ai base URLs, mirroring the Bankr pattern. Without this, relaunch skips re-applying the profile, XAI_API_KEY stays unset, and getAPIProvider() falls back to 'openai'. - buildOpenAICompatibleStartupEnv now sets XAI_API_KEY when syncing active xAI profile to the legacy fallback file. - Adds 'xai' to VALID_PROVIDERS and --provider xai CLI flag support. - Adds xAI detection to providerDiscovery label heuristics. - Adds 'xai' to legacy ProviderProfile type/isProviderProfile guard. - Adds targeted tests for relaunch alignment, flag application, and discovery labeling. Co-Authored-By: OpenClaude <openclaude@gitlawb.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@openclaude.dev> Co-authored-by: OpenClaude <openclaude@gitlawb.com>
This commit is contained in:
@@ -71,6 +71,10 @@ export function getSmallFastModel(): ModelName {
|
||||
if (getAPIProvider() === 'minimax') {
|
||||
return process.env.OPENAI_MODEL || 'MiniMax-M2.5-highspeed'
|
||||
}
|
||||
// xAI — OPENAI_MODEL carries the active Grok model; fall back to grok-3.
|
||||
if (getAPIProvider() === 'xai') {
|
||||
return process.env.OPENAI_MODEL || 'grok-3'
|
||||
}
|
||||
return getDefaultHaikuModel()
|
||||
}
|
||||
|
||||
@@ -119,7 +123,8 @@ export function getUserSpecifiedModelSetting(): ModelSetting | undefined {
|
||||
provider === 'codex' ||
|
||||
provider === 'github' ||
|
||||
provider === 'nvidia-nim' ||
|
||||
provider === 'minimax'
|
||||
provider === 'minimax' ||
|
||||
provider === 'xai'
|
||||
specifiedModel =
|
||||
(provider === 'gemini' ? process.env.GEMINI_MODEL : undefined) ||
|
||||
(provider === 'mistral' ? process.env.MISTRAL_MODEL : undefined) ||
|
||||
@@ -194,6 +199,10 @@ export function getDefaultOpusModel(): ModelName {
|
||||
if (getAPIProvider() === 'minimax') {
|
||||
return process.env.OPENAI_MODEL || 'MiniMax-M2.7'
|
||||
}
|
||||
// xAI — flagship Grok model for "opus"-equivalent.
|
||||
if (getAPIProvider() === 'xai') {
|
||||
return process.env.OPENAI_MODEL || 'grok-4'
|
||||
}
|
||||
// 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.
|
||||
@@ -236,6 +245,10 @@ export function getDefaultSonnetModel(): ModelName {
|
||||
if (getAPIProvider() === 'minimax') {
|
||||
return process.env.OPENAI_MODEL || 'MiniMax-M2.5'
|
||||
}
|
||||
// xAI — flagship Grok model for "sonnet"-equivalent.
|
||||
if (getAPIProvider() === 'xai') {
|
||||
return process.env.OPENAI_MODEL || 'grok-4'
|
||||
}
|
||||
// Default to Sonnet 4.5 for 3P since they may not have 4.6 yet
|
||||
if (getAPIProvider() !== 'firstParty') {
|
||||
return getModelStrings().sonnet45
|
||||
@@ -276,6 +289,10 @@ export function getDefaultHaikuModel(): ModelName {
|
||||
if (getAPIProvider() === 'minimax') {
|
||||
return process.env.OPENAI_MODEL || 'MiniMax-M2.5-highspeed'
|
||||
}
|
||||
// xAI — faster Grok model for "haiku"-equivalent.
|
||||
if (getAPIProvider() === 'xai') {
|
||||
return process.env.OPENAI_MODEL || 'grok-3'
|
||||
}
|
||||
|
||||
// Haiku 4.5 is available on all platforms (first-party, Foundry, Bedrock, Vertex)
|
||||
return getModelStrings().haiku45
|
||||
@@ -344,6 +361,10 @@ export function getDefaultMainLoopModelSetting(): ModelName | ModelAlias {
|
||||
if (getAPIProvider() === 'codex') {
|
||||
return process.env.OPENAI_MODEL || 'gpt-5.5'
|
||||
}
|
||||
// xAI provider: always use the configured Grok model (default grok-4)
|
||||
if (getAPIProvider() === 'xai') {
|
||||
return process.env.OPENAI_MODEL || 'grok-4'
|
||||
}
|
||||
|
||||
// Ants default to defaultModel from flag config, or Opus 1M if not configured
|
||||
if (process.env.USER_TYPE === 'ant') {
|
||||
@@ -524,7 +545,7 @@ export function renderModelSetting(setting: ModelName | ModelAlias): string {
|
||||
*/
|
||||
export function getPublicModelDisplayName(model: ModelName): string | null {
|
||||
// For OpenAI/Gemini/Codex/GitHub providers, show the actual model name not a Claude alias
|
||||
if (getAPIProvider() === 'openai' || getAPIProvider() === 'gemini' || getAPIProvider() === 'codex' || getAPIProvider() === 'github') {
|
||||
if (getAPIProvider() === 'openai' || getAPIProvider() === 'gemini' || getAPIProvider() === 'codex' || getAPIProvider() === 'github' || getAPIProvider() === 'xai') {
|
||||
// Return display names for known GitHub Copilot models
|
||||
const copilotModelNames: Record<string, string> = {
|
||||
'gpt-5.5': 'GPT-5.5',
|
||||
|
||||
Reference in New Issue
Block a user