Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
8 changes: 8 additions & 0 deletions src/auth/xai/auth-headers.test.ts
Original file line number Diff line number Diff line change
@@ -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";

Expand All @@ -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", () => {
Expand Down
5 changes: 2 additions & 3 deletions src/auth/xai/auth-headers.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
8 changes: 0 additions & 8 deletions src/auth/xai/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion src/config/xai-providers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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", () => {
Expand Down
8 changes: 6 additions & 2 deletions src/provider/grok-responses.test.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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");
Expand Down
Loading