diff --git a/bun.lock b/bun.lock index 8719f9008..61cbead3c 100644 --- a/bun.lock +++ b/bun.lock @@ -8,7 +8,7 @@ "@corbits/codex-provider": "0.1.1", "@corbits/oauth-core": "0.2.0", "@corbits/openai-responses": "0.2.1", - "@corbits/xai-provider": "0.1.1", + "@corbits/xai-provider": "0.1.2", "@intx/agent": "workspace:*", "@intx/authz": "workspace:*", "@intx/crypto": "0.3.0", @@ -257,7 +257,7 @@ "@corbits/workflows-stub": ["@corbits/workflows-stub@workspace:workflows/_stub"], - "@corbits/xai-provider": ["@corbits/xai-provider@0.1.1", "", { "dependencies": { "arktype": "^2.2.3" }, "peerDependencies": { "@corbits/oauth-core": "^0.2.0", "@corbits/openai-responses": "^0.2.0", "@intx/inference": "^0.4.0", "@intx/types": "^0.4.0" } }, "sha512-VbXdu5M300oQYQnP4Q8F0z6/Rm9kYTnIkBfo9svGlSus4rFRqEOArNhncKgFvu3Nwf9Qgooov3i8OU8gQCo/TQ=="], + "@corbits/xai-provider": ["@corbits/xai-provider@0.1.2", "", { "dependencies": { "arktype": "^2.2.3" }, "peerDependencies": { "@corbits/oauth-core": "^0.2.0", "@corbits/openai-responses": "^0.2.0", "@intx/inference": "^0.4.0", "@intx/types": "^0.4.0" } }, "sha512-4gCSLehuE922UG5DeAQLMA3iaq5MzSEgKNuq2Lb4aJqEYsQ85t8rTmu0DXs+T6mHNq2cbCI9eCF4aXuyv420iA=="], "@gar/promise-retry": ["@gar/promise-retry@1.0.3", "", {}, "sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA=="], diff --git a/package.json b/package.json index c63b7f223..0da685f9b 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "@corbits/codex-provider": "0.1.1", "@corbits/oauth-core": "0.2.0", "@corbits/openai-responses": "0.2.1", - "@corbits/xai-provider": "0.1.1", + "@corbits/xai-provider": "0.1.2", "@intx/agent": "workspace:*", "@intx/authz": "workspace:*", "@intx/crypto": "0.3.0", diff --git a/src/auth/xai/auth-headers.test.ts b/src/auth/xai/auth-headers.test.ts index 8c9e3ca29..f63db6360 100644 --- a/src/auth/xai/auth-headers.test.ts +++ b/src/auth/xai/auth-headers.test.ts @@ -1,4 +1,9 @@ import { describe, expect, test } from "bun:test"; +import { + XAI_CLIENT_IDENTIFIER, + XAI_CLIENT_VERSION, + XAI_USER_AGENT, +} from "@corbits/xai-provider"; import { xaiAuthHeadersForToken } from "./auth-headers.js"; @@ -17,6 +22,9 @@ describe("xaiAuthHeadersForToken", () => { expect(headers.authorization).toBe( `Bearer ${accessTokenWithSub("user-123")}`, ); + expect(headers["user-agent"]).toBe(XAI_USER_AGENT); + expect(headers["x-grok-client-identifier"]).toBe(XAI_CLIENT_IDENTIFIER); + expect(headers["x-grok-client-version"]).toBe(XAI_CLIENT_VERSION); }); test("omits x-grok-user-id when the JWT sub carries CR, LF, or NUL", () => { diff --git a/src/auth/xai/auth-headers.ts b/src/auth/xai/auth-headers.ts index 829fe110c..d66796dcf 100644 --- a/src/auth/xai/auth-headers.ts +++ b/src/auth/xai/auth-headers.ts @@ -1,10 +1,9 @@ -import { xaiUserIdFromAccessToken } from "@corbits/xai-provider"; - import { XAI_CLIENT_IDENTIFIER, XAI_CLIENT_VERSION, XAI_USER_AGENT, -} from "./constants.js"; + xaiUserIdFromAccessToken, +} from "@corbits/xai-provider"; export function xaiAuthHeadersForToken(token: { readonly access: string; diff --git a/src/auth/xai/constants.ts b/src/auth/xai/constants.ts index 8915cad85..ca587edbd 100644 --- a/src/auth/xai/constants.ts +++ b/src/auth/xai/constants.ts @@ -39,14 +39,6 @@ export const XAI_CALLBACK_HOST = callbackTarget.host; export const XAI_CALLBACK_PORT = callbackTarget.port; export const XAI_CALLBACK_PATH = callbackTarget.path; -// The CLI chat proxy speaks the OpenAI Responses API and authenticates the -// caller by client headers in addition to the bearer token. Values mirror the -// grok CLI's own request (captured live). Do not replace these with a product -// user-agent — the proxy and billing surfaces expect the grok-shell identity. -export const XAI_CLIENT_IDENTIFIER = "grok-shell"; -export const XAI_CLIENT_VERSION = "0.2.93"; -export const XAI_USER_AGENT = "grok-shell/0.2.93 (macos; aarch64)"; - // Cap every token request to the xAI proxy. The refresh runs on the // send path before the inference fetch arms its inactivity/total timers, so a // stalled token endpoint would otherwise freeze the agent at turn 0. diff --git a/src/config/xai-providers.test.ts b/src/config/xai-providers.test.ts index c642b8eb4..dae4aae24 100644 --- a/src/config/xai-providers.test.ts +++ b/src/config/xai-providers.test.ts @@ -18,7 +18,7 @@ import { describe("xAI OAuth provider projection", () => { test("default models lead with the CLI coding model", () => { expect(XAI_DEFAULT_MODELS.length).toBeGreaterThan(1); - expect(XAI_DEFAULT_MODELS[0]).toBe("grok-4.5"); + expect(XAI_DEFAULT_MODELS[0]).toBe("grok-4.7"); }); test("skips grok-4.7 insert when the vendor list already includes it", () => { diff --git a/src/provider/grok-responses.test.ts b/src/provider/grok-responses.test.ts index 41495f7c4..4cf4e2fa3 100644 --- a/src/provider/grok-responses.test.ts +++ b/src/provider/grok-responses.test.ts @@ -1,4 +1,8 @@ import { describe, expect, test } from "bun:test"; +import { + XAI_CLIENT_IDENTIFIER, + XAI_CLIENT_VERSION, +} from "@corbits/xai-provider"; import { BEARER_CREDENTIAL_SENTINEL } from "@intx/inference"; import type { ConversationTurn, @@ -254,8 +258,8 @@ describe("grok-responses buildRequest", () => { ); expect(req.url).toBe("/responses"); expect(req.headers["authorization"]).toBe(BEARER_CREDENTIAL_SENTINEL); - expect(req.headers["x-grok-client-identifier"]).toBe("grok-shell"); - expect(req.headers["x-grok-client-version"]).toBe("0.2.93"); + expect(req.headers["x-grok-client-identifier"]).toBe(XAI_CLIENT_IDENTIFIER); + expect(req.headers["x-grok-client-version"]).toBe(XAI_CLIENT_VERSION); expect(req.headers["x-grok-model-override"]).toBe("grok-4.5"); expect(req.headers["x-grok-user-id"]).toBe("user-123"); expect(req.headers["accept"]).toBe("text/event-stream");