Merge PR #8772: feat(catalog): default paid xAI and SuperGrok to grok-4.6 (@geraint0923)

This commit is contained in:
can1357
2026-08-17 16:00:42 +03:00
8 changed files with 33 additions and 37 deletions
+1 -1
View File
@@ -1566,7 +1566,7 @@ xAI Grok OAuth provides subscription-backed access (SuperGrok / X Premium+) to x
- **Usage Tracking**: `xaiOauthUsageProvider` (`packages/ai/src/usage/xai-oauth.ts`) queries `https://cli-chat-proxy.grok.com/v1/billing` (`validateXAIBillingEndpoint` pins to HTTPS `*.grok.com`) with header `X-XAI-Token-Auth: xai-grok-cli` (`getXAICliBillingHeaders`). Only accepts valid OAuth bearer credentials. Probes legacy weekly credits (`?format=credits`, `parseWeeklyBillingConfig` for `creditUsagePercent` and `productUsage`) and unified monthly quota (`parseMonthlyBillingConfig` for `monthlyLimit` and `used`), plus positive `onDemandCap` / `onDemandUsed` limits.
### Catalog model handling
- **Curated Models & Static Seed**: `XAI_OAUTH_CURATED_MODELS` (`packages/catalog/src/provider-models/openai-compat.ts`) defines static models (`grok-build`, `grok-build-0.1`, `grok-4.3`, `grok-4.5`, `grok-4.20-multi-agent-0309`, `grok-4.20-0309-reasoning`, `grok-4.20-0309-non-reasoning`, `grok-composer-2.5-fast`) with zero cost (`cost: 0`). Default model is `grok-4.3` (`descriptors.ts`). `buildXaiOAuthStaticSeed` seeds `ModelRegistry` synchronously at boot so `modelRoles.default = "xai-oauth/<id>"` works before dynamic refresh.
- **Curated Models & Static Seed**: `XAI_OAUTH_CURATED_MODELS` (`packages/catalog/src/provider-models/openai-compat.ts`) defines static models (`grok-build`, `grok-build-0.1`, `grok-4.3`, `grok-4.5`, `grok-4.6`, `grok-4.20-multi-agent-0309`, `grok-4.20-0309-reasoning`, `grok-4.20-0309-non-reasoning`, `grok-composer-2.5-fast`) with zero cost (`cost: 0`). Default model is `grok-4.6` (`descriptors.ts`). `buildXaiOAuthStaticSeed` seeds `ModelRegistry` synchronously at boot so `modelRoles.default = "xai-oauth/<id>"` works before dynamic refresh.
- **Dynamic Curation Overlay**: `applyXAIOAuthCuration` (`openai-compat.ts`, `xaiOAuthModelManagerOptions`) filters non-chat prefixes (`grok-imagine-`, `grok-stt-`, `grok-voice-`), overlays curated context windows (up to 2M), sets `maxTokens` equal to `contextWindow`, preserves image capabilities and reasoning flags, and injects missing curated models.
- **Reference Resolution Exclusion**: `isZeroCostXaiOAuthCandidate` (`packages/catalog/src/identity/reference.ts`) excludes zero-cost subscription entries from reference index matching so subscription pricing and limits do not override public/paid Grok references.
+3 -3
View File
@@ -2698,7 +2698,7 @@ export class AuthStorage {
/**
* Whether a request could resolve a key for this provider, including
* cross-provider env aliases (`xai-oauth` borrowing `XAI_API_KEY`).
* Use this for explicit model preflight (`xai-oauth/grok-4.5`); use
* Use this for explicit model preflight (`xai-oauth/grok-4.6`); use
* {@link hasAuth} for auto-availability so the default picker stays on
* paid `xai` when only `XAI_API_KEY` is set.
*/
@@ -2732,8 +2732,8 @@ export class AuthStorage {
* `getEnvApiKey("xai-oauth")` also accepts `XAI_API_KEY` so an explicit
* `xai-oauth/…` stream can still borrow the paid key. Availability and
* origin must not: otherwise an API-key-only setup marks SuperGrok as
* signed in and `pickDefaultAvailableModel` prefers `xai-oauth/grok-4.5`
* over paid `xai/grok-4.5`.
* signed in and `pickDefaultAvailableModel` prefers `xai-oauth/grok-4.6`
* over paid `xai/grok-4.6`.
*/
#hasDedicatedEnvAuth(provider: string): boolean {
if (provider === "xai-oauth") {
+5
View File
@@ -6,6 +6,11 @@
- Raised the GPT-5.6 Sol/Terra/Luna context window on the Codex transport (openai-codex) from 372K to 1M tokens: OpenAI enabled the 1M window for subscription Codex on 2026-08-16, but the Codex model registry still reports the stale 272,000, so discovery now floors these SKUs at 1,000,000 instead of trusting the reported value ([openai/codex#38917](https://github.com/openai/codex/issues/38917)).
### Changed
- Changed the paid xAI (XAI_API_KEY) and SuperGrok (xai-oauth) default models to grok-4.6.
## [17.3.5] - 2026-08-16
### Added
@@ -478,13 +478,13 @@ export const CATALOG_PROVIDERS = [
},
{
id: "xai",
defaultModel: "grok-4.5",
defaultModel: "grok-4.6",
envVars: ["XAI_API_KEY"],
createModelManagerOptions: (config: ModelManagerConfig) => xaiModelManagerOptions(config),
},
{
id: "xai-oauth",
defaultModel: "grok-4.5",
defaultModel: "grok-4.6",
envVars: ["XAI_OAUTH_TOKEN", "XAI_API_KEY"],
createModelManagerOptions: (config: ModelManagerConfig) => xaiOAuthModelManagerOptions(config),
catalogDiscovery: {
@@ -4,7 +4,7 @@ import * as os from "node:os";
import * as path from "node:path";
import { resolveProviderModels } from "@oh-my-pi/pi-catalog/model-manager";
import { getBundledModels } from "@oh-my-pi/pi-catalog/models";
import { CATALOG_PROVIDERS } from "@oh-my-pi/pi-catalog/provider-models/descriptors";
import { CATALOG_PROVIDERS, DEFAULT_MODEL_PER_PROVIDER } from "@oh-my-pi/pi-catalog/provider-models/descriptors";
import { xaiModelManagerOptions } from "@oh-my-pi/pi-catalog/provider-models/openai-compat";
import type { ModelSpec } from "@oh-my-pi/pi-catalog/types";
@@ -37,13 +37,18 @@ describe("paid xai (XAI_API_KEY) Responses contract", () => {
it("registers xai on the catalog Responses discovery path", () => {
const entry = CATALOG_PROVIDERS.find(provider => provider.id === "xai");
expect(entry, "xai catalog descriptor").toBeDefined();
expect(entry!.defaultModel).toBe("grok-4.5");
expect(entry!.defaultModel).toBe("grok-4.6");
expect(DEFAULT_MODEL_PER_PROVIDER.xai).toBe("grok-4.6");
expect(
getBundledModels("xai").find(model => model.id === "grok-4.6"),
"xai/grok-4.6 must be bundled for the default",
).toBeDefined();
expect(entry!.envVars).toContain("XAI_API_KEY");
const options = xaiModelManagerOptions({ apiKey: "test-key" });
expect(options.providerId).toBe("xai");
expect(options.fetchDynamicModels, "live /v1/models overlay").toBeTypeOf("function");
expect(options.dropCachedModelIdsOnStaticMismatch).toEqual(getBundledModels("xai").map(model => model.id));
expect(options.dropCachedModelIdsOnStaticMismatch).toContain("grok-4.5");
expect(options.dropCachedModelIdsOnStaticMismatch).toContain("grok-4.6");
});
it("bundles every paid xai chat model on openai-responses", () => {
@@ -18,11 +18,11 @@ describe("xai-oauth bundled catalog (regression)", () => {
(MODELS_JSON as unknown as Record<string, Record<string, ModelSpec<"openai-responses">>>)["xai-oauth"] ?? {};
const seed = buildXaiOAuthStaticSeed();
it("defaults SuperGrok selection to grok-4.5", () => {
it("defaults SuperGrok selection to grok-4.6", () => {
const entry = CATALOG_PROVIDERS.find(provider => provider.id === "xai-oauth");
expect(entry?.defaultModel).toBe("grok-4.5");
expect(DEFAULT_MODEL_PER_PROVIDER["xai-oauth"]).toBe("grok-4.5");
expect(bundled["grok-4.5"], "xai-oauth/grok-4.5 must be bundled for the default").toBeDefined();
expect(entry?.defaultModel).toBe("grok-4.6");
expect(DEFAULT_MODEL_PER_PROVIDER["xai-oauth"]).toBe("grok-4.6");
expect(bundled["grok-4.6"], "xai-oauth/grok-4.6 must be bundled for the default").toBeDefined();
});
it("bundles every curated id", () => {
+4
View File
@@ -2,6 +2,10 @@
## [Unreleased]
### Changed
- Updated the default model for XAI_API_KEY (xai) and SuperGrok OAuth (xai-oauth) to grok-4.6. Automatic model selection continues to prefer paid xai/grok-4.6 when only XAI_API_KEY is set, with xai-oauth/grok-4.6 still available explicitly.
### Added
- Added `ExtensionAPI.registerFileWriteFallback(handler)` and `ExtensionAPI.registerFileDeleteFallback(handler)`, letting an extension supply a fallback writer or deleter that is consulted when a native `write`, `edit`, or `apply_patch` byte-write or unlink is denied with a permission error (`EPERM`/`EACCES`/`EROFS`) — for hosts that embed the agent inside a sandbox that denies direct filesystem access but exposes a privileged channel. The brokered path is symlink-resolved so a handler's allowlist sees the real destination, a destination that cannot be resolved is not brokered at all, and `req.sessionId` names the session that issued the mutation so a handler sharing the process-wide registry can enforce policy per session. See [`docs/extensions.md`](../../docs/extensions.md).
@@ -1,6 +1,7 @@
import { describe, expect, test } from "bun:test";
import { type Api, Effort, type Model } from "@oh-my-pi/pi-ai";
import { buildModel } from "@oh-my-pi/pi-catalog/build";
import { getBundledModel } from "@oh-my-pi/pi-catalog/models";
import { DEFAULT_MODEL_PER_PROVIDER } from "@oh-my-pi/pi-catalog/provider-models";
import {
expandRoleAlias,
@@ -439,30 +440,11 @@ describe("pickDefaultAvailableModel", () => {
});
test("prefers SuperGrok over paid xAI when both defaults are present", () => {
const paid = buildModel({
id: "grok-4.5",
name: "Grok 4.5",
api: "openai-responses",
provider: "xai",
baseUrl: "https://api.x.ai/v1",
reasoning: true,
input: ["text", "image"],
cost: { input: 2, output: 6, cacheRead: 0.3, cacheWrite: 0 },
contextWindow: 500000,
maxTokens: 500000,
});
const oauth = buildModel({
id: "grok-4.5",
name: "Grok 4.5",
api: "openai-responses",
provider: "xai-oauth",
baseUrl: "https://api.x.ai/v1",
reasoning: true,
input: ["text", "image"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 500000,
maxTokens: 500000,
});
const paid = getBundledModel("xai", DEFAULT_MODEL_PER_PROVIDER.xai);
const oauth = getBundledModel("xai-oauth", DEFAULT_MODEL_PER_PROVIDER["xai-oauth"]);
if (!paid || !oauth) {
throw new Error("Expected bundled xAI provider defaults");
}
expect(pickDefaultAvailableModel([paid, oauth])?.provider).toBe("xai-oauth");
expect(pickDefaultAvailableModel([paid])?.provider).toBe("xai");