fix(ai): prevent removed xAI models regenerating, closes #6736
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
### Fixed
|
||||
|
||||
- Fixed Kimi Coding K3 thinking-level metadata to expose only the supported `max` level ([#6737](https://github.com/earendil-works/pi/issues/6737)).
|
||||
- Fixed catalog generation restoring xAI models removed in 0.80.9 ([#6736](https://github.com/earendil-works/pi/issues/6736)).
|
||||
|
||||
## [0.80.9] - 2026-07-16
|
||||
|
||||
|
||||
@@ -747,7 +747,7 @@ Many models support thinking/reasoning capabilities where they can show their in
|
||||
const model = models.getModel('anthropic', 'claude-sonnet-4-5')!;
|
||||
// or models.getModel('openai', 'gpt-5-mini');
|
||||
// or models.getModel('google', 'gemini-2.5-flash');
|
||||
// or models.getModel('xai', 'grok-code-fast-1');
|
||||
// or models.getModel('xai', 'grok-4.5');
|
||||
|
||||
// Check if model supports reasoning
|
||||
if (model.reasoning) {
|
||||
|
||||
@@ -302,6 +302,13 @@ const OPENAI_RESPONSES_NONE_REASONING_MODELS = new Set([
|
||||
"gpt-5.6-luna",
|
||||
]);
|
||||
const XAI_RESPONSES_MODEL_ID = "grok-4.5";
|
||||
const XAI_BUILTIN_EXCLUDED_MODEL_IDS = new Set([
|
||||
"grok-3",
|
||||
"grok-3-fast",
|
||||
"grok-4.20-0309-non-reasoning",
|
||||
"grok-4.20-0309-reasoning",
|
||||
"grok-code-fast-1",
|
||||
]);
|
||||
const XAI_RESPONSES_EFFORT_LEVEL_MAP = {
|
||||
off: null,
|
||||
minimal: null,
|
||||
@@ -1783,6 +1790,7 @@ async function generateModels() {
|
||||
// Combine models (models.dev has priority)
|
||||
const allModels = [...modelsDevModels, ...openRouterModels, ...aiGatewayModels].filter(
|
||||
(model) =>
|
||||
!(model.provider === "xai" && XAI_BUILTIN_EXCLUDED_MODEL_IDS.has(model.id)) &&
|
||||
!((model.provider === "opencode" || model.provider === "opencode-go") && model.id === "gpt-5.3-codex-spark"),
|
||||
);
|
||||
|
||||
@@ -2142,56 +2150,6 @@ async function generateModels() {
|
||||
];
|
||||
allModels.push(...codexModels);
|
||||
|
||||
// Add missing Grok models
|
||||
const missingGrokModels: Model<"openai-completions">[] = [
|
||||
{
|
||||
id: "grok-3",
|
||||
name: "Grok 3",
|
||||
api: "openai-completions",
|
||||
baseUrl: "https://api.x.ai/v1",
|
||||
provider: "xai",
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: { input: 3, output: 15, cacheRead: 0.75, cacheWrite: 0 },
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
},
|
||||
{
|
||||
id: "grok-3-fast",
|
||||
name: "Grok 3 Fast",
|
||||
api: "openai-completions",
|
||||
baseUrl: "https://api.x.ai/v1",
|
||||
provider: "xai",
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: { input: 5, output: 25, cacheRead: 1.25, cacheWrite: 0 },
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
},
|
||||
{
|
||||
id: "grok-code-fast-1",
|
||||
name: "Grok Code Fast 1",
|
||||
api: "openai-completions",
|
||||
baseUrl: "https://api.x.ai/v1",
|
||||
provider: "xai",
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: {
|
||||
input: 0.2,
|
||||
output: 1.5,
|
||||
cacheRead: 0.02,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 32768,
|
||||
maxTokens: 8192,
|
||||
},
|
||||
];
|
||||
for (const model of missingGrokModels) {
|
||||
if (!allModels.some(m => m.provider === model.provider && m.id === model.id)) {
|
||||
allModels.push(model);
|
||||
}
|
||||
}
|
||||
|
||||
// Add missing Mistral Medium 3.5 model until models.dev includes it
|
||||
if (!allModels.some(m => m.provider === "mistral" && m.id === "mistral-medium-3.5")) {
|
||||
allModels.push({
|
||||
|
||||
@@ -4706,9 +4706,9 @@ export const OPENROUTER_MODELS = {
|
||||
thinkingLevelMap: {"xhigh":"xhigh"},
|
||||
input: ["text"],
|
||||
cost: {
|
||||
input: 0.9212,
|
||||
output: 2.8952,
|
||||
cacheRead: 0.17108,
|
||||
input: 0.9198,
|
||||
output: 2.8908,
|
||||
cacheRead: 0.17082,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 1048576,
|
||||
|
||||
@@ -4,78 +4,6 @@
|
||||
import type { Model } from "../types.ts";
|
||||
|
||||
export const XAI_MODELS = {
|
||||
"grok-3": {
|
||||
id: "grok-3",
|
||||
name: "Grok 3",
|
||||
api: "openai-completions",
|
||||
provider: "xai",
|
||||
baseUrl: "https://api.x.ai/v1",
|
||||
compat: {"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false},
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: {
|
||||
input: 3,
|
||||
output: 15,
|
||||
cacheRead: 0.75,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
} satisfies Model<"openai-completions">,
|
||||
"grok-3-fast": {
|
||||
id: "grok-3-fast",
|
||||
name: "Grok 3 Fast",
|
||||
api: "openai-completions",
|
||||
provider: "xai",
|
||||
baseUrl: "https://api.x.ai/v1",
|
||||
compat: {"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false},
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: {
|
||||
input: 5,
|
||||
output: 25,
|
||||
cacheRead: 1.25,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
} satisfies Model<"openai-completions">,
|
||||
"grok-4.20-0309-non-reasoning": {
|
||||
id: "grok-4.20-0309-non-reasoning",
|
||||
name: "Grok 4.20 (Non-Reasoning)",
|
||||
api: "openai-completions",
|
||||
provider: "xai",
|
||||
baseUrl: "https://api.x.ai/v1",
|
||||
compat: {"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false},
|
||||
reasoning: false,
|
||||
input: ["text", "image"],
|
||||
cost: {
|
||||
input: 1.25,
|
||||
output: 2.5,
|
||||
cacheRead: 0.2,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 1000000,
|
||||
maxTokens: 30000,
|
||||
} satisfies Model<"openai-completions">,
|
||||
"grok-4.20-0309-reasoning": {
|
||||
id: "grok-4.20-0309-reasoning",
|
||||
name: "Grok 4.20 (Reasoning)",
|
||||
api: "openai-completions",
|
||||
provider: "xai",
|
||||
baseUrl: "https://api.x.ai/v1",
|
||||
compat: {"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false},
|
||||
reasoning: true,
|
||||
input: ["text", "image"],
|
||||
cost: {
|
||||
input: 1.25,
|
||||
output: 2.5,
|
||||
cacheRead: 0.2,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 1000000,
|
||||
maxTokens: 30000,
|
||||
} satisfies Model<"openai-completions">,
|
||||
"grok-4.3": {
|
||||
id: "grok-4.3",
|
||||
name: "Grok 4.3",
|
||||
@@ -131,22 +59,4 @@ export const XAI_MODELS = {
|
||||
contextWindow: 256000,
|
||||
maxTokens: 256000,
|
||||
} satisfies Model<"openai-completions">,
|
||||
"grok-code-fast-1": {
|
||||
id: "grok-code-fast-1",
|
||||
name: "Grok Code Fast 1",
|
||||
api: "openai-completions",
|
||||
provider: "xai",
|
||||
baseUrl: "https://api.x.ai/v1",
|
||||
compat: {"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false},
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: {
|
||||
input: 0.2,
|
||||
output: 1.5,
|
||||
cacheRead: 0.02,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 32768,
|
||||
maxTokens: 8192,
|
||||
} satisfies Model<"openai-completions">,
|
||||
} as const;
|
||||
|
||||
@@ -262,7 +262,7 @@ describe("Context overflow error handling", () => {
|
||||
// =============================================================================
|
||||
|
||||
describe.skipIf(!process.env.XAI_API_KEY)("xAI", () => {
|
||||
it("grok-3-fast - should detect overflow via isContextOverflow", async () => {
|
||||
it("grok-4.3 - should detect overflow via isContextOverflow", async () => {
|
||||
const model = getModel("xai", "grok-4.3");
|
||||
const result = await testContextOverflow(model, process.env.XAI_API_KEY!);
|
||||
logResult(result);
|
||||
|
||||
@@ -79,7 +79,7 @@ const PROVIDER_MODEL_PAIRS: ProviderModelPair[] = [
|
||||
label: "bedrock-claude-sonnet-4-5",
|
||||
},
|
||||
// xAI
|
||||
{ provider: "xai", model: "grok-code-fast-1", label: "xai-grok-code-fast-1" },
|
||||
{ provider: "xai", model: "grok-4.3", label: "xai-grok-4.3" },
|
||||
// Cerebras
|
||||
{ provider: "cerebras", model: "zai-glm-4.7", label: "cerebras-zai-glm-4.7" },
|
||||
// Cloudflare Workers AI
|
||||
|
||||
@@ -542,7 +542,7 @@ describe("Generate E2E Tests", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe.skipIf(!process.env.XAI_API_KEY)("xAI Provider (grok-code-fast-1 via OpenAI Completions)", () => {
|
||||
describe.skipIf(!process.env.XAI_API_KEY)("xAI Provider (grok-4.3 via OpenAI Completions)", () => {
|
||||
const llm = getModel("xai", "grok-4.3");
|
||||
|
||||
it("should complete basic text generation", { retry: 3 }, async () => {
|
||||
|
||||
@@ -244,10 +244,7 @@ describe("totalTokens field", () => {
|
||||
// =========================================================================
|
||||
|
||||
describe.skipIf(!process.env.XAI_API_KEY)("xAI", () => {
|
||||
it(
|
||||
"grok-3-fast - should return totalTokens equal to sum of components",
|
||||
{ retry: 3, timeout: 60000 },
|
||||
async () => {
|
||||
it("grok-4.3 - should return totalTokens equal to sum of components", { retry: 3, timeout: 60000 }, async () => {
|
||||
const llm = getModel("xai", "grok-4.3");
|
||||
|
||||
console.log(`\nxAI / ${llm.id}:`);
|
||||
@@ -258,8 +255,7 @@ describe("totalTokens field", () => {
|
||||
|
||||
assertTotalTokensEqualsComponents(first);
|
||||
assertTotalTokensEqualsComponents(second);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// =========================================================================
|
||||
|
||||
@@ -60,6 +60,18 @@ describe("xAI Responses provider", () => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("excludes retired and redundant models from the built-in catalog", () => {
|
||||
for (const modelId of [
|
||||
"grok-3",
|
||||
"grok-3-fast",
|
||||
"grok-4.20-0309-non-reasoning",
|
||||
"grok-4.20-0309-reasoning",
|
||||
"grok-code-fast-1",
|
||||
]) {
|
||||
expect(Object.keys(XAI_MODELS)).not.toContain(modelId);
|
||||
}
|
||||
});
|
||||
|
||||
it("uses Responses with low/medium/high efforts only for Grok 4.5", () => {
|
||||
expect(XAI_MODELS["grok-4.5"].api).toBe("openai-responses");
|
||||
expect(getSupportedThinkingLevels(XAI_MODELS["grok-4.5"])).toEqual(["low", "medium", "high"]);
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed inherited catalog generation restoring xAI models removed in 0.80.9 ([#6736](https://github.com/earendil-works/pi/issues/6736)).
|
||||
|
||||
## [0.80.9] - 2026-07-16
|
||||
|
||||
### New Features
|
||||
|
||||
Reference in New Issue
Block a user