From b467a83c0fe5bf6adb1ff158db0d9f8997802427 Mon Sep 17 00:00:00 2001 From: ggbdpq Date: Thu, 1 Oct 2026 06:14:37 +0800 Subject: [PATCH] fix(xai): bump pinned grok client version to 1.0.44 for chat-proxy xAI raised the minimum accepted x-grok-client-version on cli-chat-proxy.grok.com, so every xAI OAuth chat request through the CLI chat-proxy failed with HTTP 426 ("Your Grok CLI version (0.2.120) is outdated"). /v1/models is not gated, so discovery looked healthy while inference was dead. Bump the pin to the current stable Grok CLI version (1.0.44) and record the observed server floor in the constant's comment. Both x-grok-client-version and the derived User-Agent ship from this one constant. Regression tests lock three things: the pinned version meets the known server floor (red against 0.2.120), the two identity headers stay derived from the same constant, and the per-auth `header:*` custom header override still wins over the pin - the documented operator escape hatch when xAI ratchets the floor again. Closes #6249 Generated-by: GLM-5.3-Flash (ZCode) --- .../executor/xai_client_version_test.go | 76 +++++++++++++++++++ internal/runtime/executor/xai_executor.go | 6 +- 2 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 internal/runtime/executor/xai_client_version_test.go diff --git a/internal/runtime/executor/xai_client_version_test.go b/internal/runtime/executor/xai_client_version_test.go new file mode 100644 index 000000000..784780875 --- /dev/null +++ b/internal/runtime/executor/xai_client_version_test.go @@ -0,0 +1,76 @@ +package executor + +import ( + "net/http" + "strconv" + "strings" + "testing" + + cliproxyauth "github.com/router-for-me/CLIProxyAPI/v8/sdk/cliproxy/auth" +) + +// xaiVersionAtLeast compares dotted numeric version strings. +func xaiVersionAtLeast(got, floor string) bool { + gotParts := strings.Split(got, ".") + floorParts := strings.Split(floor, ".") + for i := 0; i < len(gotParts) || i < len(floorParts); i++ { + var g, f int + if i < len(gotParts) { + g, _ = strconv.Atoi(gotParts[i]) + } + if i < len(floorParts) { + f, _ = strconv.Atoi(floorParts[i]) + } + if g != f { + return g > f + } + } + return true +} + +func TestXAIChatProxyClientVersionMeetsServerFloor(t *testing.T) { + // cli-chat-proxy.grok.com started rejecting client versions older than + // 1.0.13 with HTTP 426 ("Your Grok CLI version is outdated"); see #6249. + const serverFloor = "1.0.13" + if !xaiVersionAtLeast(xaiClientVersionValue, serverFloor) { + t.Fatalf("xaiClientVersionValue = %q, cli-chat-proxy rejects clients older than %s with 426", xaiClientVersionValue, serverFloor) + } +} + +func TestXAIChatProxyIdentityHeadersDeriveFromOneConstant(t *testing.T) { + auth := &cliproxyauth.Auth{ + Provider: "xai", + Attributes: map[string]string{"auth_kind": "oauth"}, + } + req, err := http.NewRequest(http.MethodPost, xaiChatBaseURL(auth)+"/chat/completions", nil) + if err != nil { + t.Fatal(err) + } + applyXAIChatHeaders(req, auth, "token", false, "") + + if got := req.Header.Get(xaiClientVersionHeader); got != xaiClientVersionValue { + t.Fatalf("%s = %q, want %q", xaiClientVersionHeader, got, xaiClientVersionValue) + } + if got, want := req.Header.Get("User-Agent"), "xai-grok-workspace/"+xaiClientVersionValue; got != want { + t.Fatalf("User-Agent = %q, want %q (must derive from xaiClientVersionValue)", got, want) + } +} + +func TestXAIChatProxyCustomHeadersOverridePinnedVersion(t *testing.T) { + auth := &cliproxyauth.Auth{ + Provider: "xai", + Attributes: map[string]string{ + "auth_kind": "oauth", + "header:x-grok-client-version": "9.9.9", + }, + } + req, err := http.NewRequest(http.MethodPost, xaiChatBaseURL(auth)+"/chat/completions", nil) + if err != nil { + t.Fatal(err) + } + applyXAIChatHeaders(req, auth, "token", false, "") + + if got := req.Header.Get(xaiClientVersionHeader); got != "9.9.9" { + t.Fatalf("%s = %q, want the per-auth custom header to override the pin", xaiClientVersionHeader, got) + } +} diff --git a/internal/runtime/executor/xai_executor.go b/internal/runtime/executor/xai_executor.go index 54c817143..4991a62a0 100644 --- a/internal/runtime/executor/xai_executor.go +++ b/internal/runtime/executor/xai_executor.go @@ -48,8 +48,10 @@ const ( xaiTokenAuthHeader = "X-XAI-Token-Auth" xaiTokenAuthValue = "xai-grok-cli" xaiClientVersionHeader = "x-grok-client-version" - // Keep in sync with the current Grok CLI client version that chat-proxy expects. - xaiClientVersionValue = "0.2.120" + // Keep in sync with the current Grok CLI client version that chat-proxy + // expects. The server rejects older versions with HTTP 426; it required + // 1.0.13+ as of 2026-10-01 (#6249). + xaiClientVersionValue = "1.0.44" xaiClientIdentifierHeader = "x-grok-client-identifier" xaiClientIdentifierValue = "grok-shell" xaiAuthenticateResponseHeader = "x-authenticateresponse"