fix(onboard): align xAI default model to grok-4
This commit is contained in:
@@ -36,7 +36,7 @@ export async function applyAuthChoiceXAI(
|
|||||||
let hasCredential = false;
|
let hasCredential = false;
|
||||||
const optsKey = params.opts?.xaiApiKey?.trim();
|
const optsKey = params.opts?.xaiApiKey?.trim();
|
||||||
if (optsKey) {
|
if (optsKey) {
|
||||||
await setXaiApiKey(normalizeApiKeyInput(optsKey), params.agentDir);
|
setXaiApiKey(normalizeApiKeyInput(optsKey), params.agentDir);
|
||||||
hasCredential = true;
|
hasCredential = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ export async function applyAuthChoiceXAI(
|
|||||||
initialValue: true,
|
initialValue: true,
|
||||||
});
|
});
|
||||||
if (useExisting) {
|
if (useExisting) {
|
||||||
await setXaiApiKey(envKey.apiKey, params.agentDir);
|
setXaiApiKey(envKey.apiKey, params.agentDir);
|
||||||
hasCredential = true;
|
hasCredential = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ export async function applyAuthChoiceXAI(
|
|||||||
message: "Enter xAI API key",
|
message: "Enter xAI API key",
|
||||||
validate: validateApiKeyInput,
|
validate: validateApiKeyInput,
|
||||||
});
|
});
|
||||||
await setXaiApiKey(normalizeApiKeyInput(String(key)), params.agentDir);
|
setXaiApiKey(normalizeApiKeyInput(String(key)), params.agentDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
nextConfig = applyAuthProfileConfig(nextConfig, {
|
nextConfig = applyAuthProfileConfig(nextConfig, {
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ describe("applyAuthChoice", () => {
|
|||||||
mode: "api_key",
|
mode: "api_key",
|
||||||
});
|
});
|
||||||
expect(result.config.agents?.defaults?.model?.primary).toBe("openai/gpt-4o-mini");
|
expect(result.config.agents?.defaults?.model?.primary).toBe("openai/gpt-4o-mini");
|
||||||
expect(result.agentModelOverride).toBe("xai/grok-2-latest");
|
expect(result.agentModelOverride).toBe("xai/grok-4");
|
||||||
|
|
||||||
const authProfilePath = authProfilePathFor(requireAgentDir());
|
const authProfilePath = authProfilePathFor(requireAgentDir());
|
||||||
const raw = await fs.readFile(authProfilePath, "utf8");
|
const raw = await fs.readFile(authProfilePath, "utf8");
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ export async function setOpencodeZenApiKey(key: string, agentDir?: string) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function setXaiApiKey(key: string, agentDir?: string) {
|
export function setXaiApiKey(key: string, agentDir?: string) {
|
||||||
upsertAuthProfile({
|
upsertAuthProfile({
|
||||||
profileId: "xai:default",
|
profileId: "xai:default",
|
||||||
credential: {
|
credential: {
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ export function buildMoonshotModelDefinition(): ModelDefinitionConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const XAI_BASE_URL = "https://api.x.ai/v1";
|
export const XAI_BASE_URL = "https://api.x.ai/v1";
|
||||||
export const XAI_DEFAULT_MODEL_ID = "grok-2-latest";
|
export const XAI_DEFAULT_MODEL_ID = "grok-4";
|
||||||
export const XAI_DEFAULT_MODEL_REF = `xai/${XAI_DEFAULT_MODEL_ID}`;
|
export const XAI_DEFAULT_MODEL_REF = `xai/${XAI_DEFAULT_MODEL_ID}`;
|
||||||
export const XAI_DEFAULT_CONTEXT_WINDOW = 131072;
|
export const XAI_DEFAULT_CONTEXT_WINDOW = 131072;
|
||||||
export const XAI_DEFAULT_MAX_TOKENS = 8192;
|
export const XAI_DEFAULT_MAX_TOKENS = 8192;
|
||||||
@@ -108,7 +108,7 @@ export const XAI_DEFAULT_COST = {
|
|||||||
export function buildXaiModelDefinition(): ModelDefinitionConfig {
|
export function buildXaiModelDefinition(): ModelDefinitionConfig {
|
||||||
return {
|
return {
|
||||||
id: XAI_DEFAULT_MODEL_ID,
|
id: XAI_DEFAULT_MODEL_ID,
|
||||||
name: "Grok 2",
|
name: "Grok 4",
|
||||||
reasoning: false,
|
reasoning: false,
|
||||||
input: ["text"],
|
input: ["text"],
|
||||||
cost: XAI_DEFAULT_COST,
|
cost: XAI_DEFAULT_COST,
|
||||||
|
|||||||
@@ -13,11 +13,14 @@ import {
|
|||||||
applyOpenrouterProviderConfig,
|
applyOpenrouterProviderConfig,
|
||||||
applySyntheticConfig,
|
applySyntheticConfig,
|
||||||
applySyntheticProviderConfig,
|
applySyntheticProviderConfig,
|
||||||
|
applyXaiConfig,
|
||||||
|
applyXaiProviderConfig,
|
||||||
applyXiaomiConfig,
|
applyXiaomiConfig,
|
||||||
applyXiaomiProviderConfig,
|
applyXiaomiProviderConfig,
|
||||||
OPENROUTER_DEFAULT_MODEL_REF,
|
OPENROUTER_DEFAULT_MODEL_REF,
|
||||||
SYNTHETIC_DEFAULT_MODEL_ID,
|
SYNTHETIC_DEFAULT_MODEL_ID,
|
||||||
SYNTHETIC_DEFAULT_MODEL_REF,
|
SYNTHETIC_DEFAULT_MODEL_REF,
|
||||||
|
XAI_DEFAULT_MODEL_REF,
|
||||||
setMinimaxApiKey,
|
setMinimaxApiKey,
|
||||||
writeOAuthCredentials,
|
writeOAuthCredentials,
|
||||||
} from "./onboard-auth.js";
|
} from "./onboard-auth.js";
|
||||||
@@ -389,6 +392,65 @@ describe("applyXiaomiConfig", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("applyXaiConfig", () => {
|
||||||
|
it("adds xAI provider with correct settings", () => {
|
||||||
|
const cfg = applyXaiConfig({});
|
||||||
|
expect(cfg.models?.providers?.xai).toMatchObject({
|
||||||
|
baseUrl: "https://api.x.ai/v1",
|
||||||
|
api: "openai-completions",
|
||||||
|
});
|
||||||
|
expect(cfg.agents?.defaults?.model?.primary).toBe(XAI_DEFAULT_MODEL_REF);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("preserves existing model fallbacks", () => {
|
||||||
|
const cfg = applyXaiConfig({
|
||||||
|
agents: {
|
||||||
|
defaults: {
|
||||||
|
model: { fallbacks: ["anthropic/claude-opus-4-5"] },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(cfg.agents?.defaults?.model?.fallbacks).toEqual(["anthropic/claude-opus-4-5"]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("applyXaiProviderConfig", () => {
|
||||||
|
it("adds model alias", () => {
|
||||||
|
const cfg = applyXaiProviderConfig({});
|
||||||
|
expect(cfg.agents?.defaults?.models?.[XAI_DEFAULT_MODEL_REF]?.alias).toBe("Grok");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("merges xAI models and keeps existing provider overrides", () => {
|
||||||
|
const cfg = applyXaiProviderConfig({
|
||||||
|
models: {
|
||||||
|
providers: {
|
||||||
|
xai: {
|
||||||
|
baseUrl: "https://old.example.com",
|
||||||
|
apiKey: "old-key",
|
||||||
|
api: "anthropic-messages",
|
||||||
|
models: [
|
||||||
|
{
|
||||||
|
id: "custom-model",
|
||||||
|
name: "Custom",
|
||||||
|
reasoning: false,
|
||||||
|
input: ["text"],
|
||||||
|
cost: { input: 1, output: 2, cacheRead: 0, cacheWrite: 0 },
|
||||||
|
contextWindow: 1000,
|
||||||
|
maxTokens: 100,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(cfg.models?.providers?.xai?.baseUrl).toBe("https://api.x.ai/v1");
|
||||||
|
expect(cfg.models?.providers?.xai?.api).toBe("openai-completions");
|
||||||
|
expect(cfg.models?.providers?.xai?.apiKey).toBe("old-key");
|
||||||
|
expect(cfg.models?.providers?.xai?.models.map((m) => m.id)).toEqual(["custom-model", "grok-4"]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("applyOpencodeZenProviderConfig", () => {
|
describe("applyOpencodeZenProviderConfig", () => {
|
||||||
it("adds allowlist entry for the default model", () => {
|
it("adds allowlist entry for the default model", () => {
|
||||||
const cfg = applyOpencodeZenProviderConfig({});
|
const cfg = applyOpencodeZenProviderConfig({});
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ describe("onboard (non-interactive): xAI", () => {
|
|||||||
|
|
||||||
expect(cfg.auth?.profiles?.["xai:default"]?.provider).toBe("xai");
|
expect(cfg.auth?.profiles?.["xai:default"]?.provider).toBe("xai");
|
||||||
expect(cfg.auth?.profiles?.["xai:default"]?.mode).toBe("api_key");
|
expect(cfg.auth?.profiles?.["xai:default"]?.mode).toBe("api_key");
|
||||||
expect(cfg.agents?.defaults?.model?.primary).toBe("xai/grok-2-latest");
|
expect(cfg.agents?.defaults?.model?.primary).toBe("xai/grok-4");
|
||||||
|
|
||||||
const { ensureAuthProfileStore } = await import("../agents/auth-profiles.js");
|
const { ensureAuthProfileStore } = await import("../agents/auth-profiles.js");
|
||||||
const store = ensureAuthProfileStore();
|
const store = ensureAuthProfileStore();
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ export async function applyNonInteractiveAuthChoice(params: {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (resolved.source !== "profile") {
|
if (resolved.source !== "profile") {
|
||||||
await setXaiApiKey(resolved.key);
|
setXaiApiKey(resolved.key);
|
||||||
}
|
}
|
||||||
nextConfig = applyAuthProfileConfig(nextConfig, {
|
nextConfig = applyAuthProfileConfig(nextConfig, {
|
||||||
profileId: "xai:default",
|
profileId: "xai:default",
|
||||||
|
|||||||
Reference in New Issue
Block a user