Merge PR #8772: feat(catalog): default paid xAI and SuperGrok to grok-4.6 (@geraint0923)
This commit is contained in:
@@ -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.
|
||||
|
||||
|
||||
@@ -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") {
|
||||
|
||||
@@ -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", () => {
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user