Skip to content

Commit 93fe7e1

Browse files
committed
fix(xai): case-insensitive user override for Grok CLI default headers
Reviewer MINOR: a mixed-case user header (X-Grok-Client-Version) previously coexisted with the lowercase default and merged into an invalid combined value in Bun Headers. Defaults are now dropped whenever the user overrides them under any casing.
1 parent a7a99d3 commit 93fe7e1

2 files changed

Lines changed: 23 additions & 1 deletion

File tree

src/providers/xai-transport.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ function hasHeaderCaseInsensitive(headers: Record<string, string> | undefined, n
3535
return Object.keys(headers).some(key => key.toLowerCase() === target);
3636
}
3737

38+
/** Drop default entries the user already overrides under any header-name casing. */
39+
function withoutUserOverridden(defaults: Readonly<Record<string, string>>, userHeaders: Record<string, string> | undefined): Record<string, string> {
40+
if (!userHeaders) return { ...defaults };
41+
const out: Record<string, string> = {};
42+
for (const [key, value] of Object.entries(defaults)) {
43+
if (!hasHeaderCaseInsensitive(userHeaders, key)) out[key] = value;
44+
}
45+
return out;
46+
}
47+
3848
export function deriveXaiConvId(promptCacheKey: string): string {
3949
return createHash("sha256").update(promptCacheKey).digest("hex").slice(0, 32);
4050
}
@@ -71,7 +81,7 @@ export function resolveProviderTransport(
7181
...provider,
7282
baseUrl: XAI_GROK_CLI_BASE_URL,
7383
headers: {
74-
...XAI_GROK_CLI_HEADERS,
84+
...withoutUserOverridden(XAI_GROK_CLI_HEADERS, provider.headers),
7585
...convIdHeaders,
7686
...(provider.headers ?? {}),
7787
},

tests/xai-transport.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,18 @@ describe("xAI prompt-cache conv-id affinity", () => {
141141
const convIdKeys = Object.keys(mixedResolved.headers ?? {}).filter(k => k.toLowerCase() === XAI_CONV_ID_HEADER);
142142
expect(convIdKeys).toHaveLength(1);
143143
});
144+
145+
test("mixed-case user override of a Grok CLI default header suppresses the default", () => {
146+
const custom = provider("oauth");
147+
custom.headers = { "X-Grok-Client-Version": "0.2.94" };
148+
149+
const resolved = resolveProviderTransport("xai", custom);
150+
const versionKeys = Object.keys(resolved.headers ?? {}).filter(k => k.toLowerCase() === "x-grok-client-version");
151+
expect(versionKeys).toEqual(["X-Grok-Client-Version"]);
152+
expect(resolved.headers?.["X-Grok-Client-Version"]).toBe("0.2.94");
153+
// Untouched defaults still apply.
154+
expect(resolved.headers?.["x-grok-client-identifier"]).toBe("opencodex");
155+
});
144156
});
145157

146158
describe("xAI reasoning_content cache preservation", () => {

0 commit comments

Comments
 (0)