mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-15 23:22:59 +08:00
95 lines
3.1 KiB
Go
95 lines
3.1 KiB
Go
package xai
|
|
|
|
import (
|
|
"net/http"
|
|
"os"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"golang.org/x/mod/semver"
|
|
)
|
|
|
|
// Fixed Grok Build / CLI-chat-proxy client identity.
|
|
// These values are intentionally pinned in-binary (not scraped from live CLI).
|
|
// Operators may bump the version via XAI_GROK_CLI_VERSION without a release.
|
|
const (
|
|
// CLIProxyHost is the hostname that requires the official CLI identity headers.
|
|
CLIProxyHost = "cli-chat-proxy.grok.com"
|
|
|
|
// CLIStableVersion is the known-good minimum client version accepted by cli-chat-proxy.
|
|
CLIStableVersion = "1.0.13"
|
|
|
|
// CLIVersionEnv is the optional operator override for CLIStableVersion.
|
|
CLIVersionEnv = "XAI_GROK_CLI_VERSION"
|
|
|
|
// CLITokenAuth is required by cli-chat-proxy for Grok Build OAuth tokens.
|
|
CLITokenAuth = "xai-grok-cli"
|
|
|
|
// CLIClientIdentifier 对齐官方交互式 CLI 主请求的客户端标识。
|
|
CLIClientIdentifier = "grok-pager"
|
|
|
|
// CLIClientMode 对齐官方 CLI 正常交互模式。
|
|
CLIClientMode = "interactive"
|
|
)
|
|
|
|
// ResolveCLIVersion returns a supported CLI client version.
|
|
// Empty or invalid overrides fall back to CLIClientVersion (the pinned
|
|
// preferred client pin in billing.go). CLIStableVersion is only the minimum
|
|
// accepted by IsSupportedCLIVersion, not the default identity we advertise.
|
|
func ResolveCLIVersion() string {
|
|
version := strings.TrimSpace(os.Getenv(CLIVersionEnv))
|
|
if !IsSupportedCLIVersion(version) {
|
|
return CLIClientVersion
|
|
}
|
|
return version
|
|
}
|
|
|
|
// IsSupportedCLIVersion reports whether version is a valid semver string at or
|
|
// above CLIStableVersion (prereleases below a higher release are rejected when
|
|
// they compare less than the stable pin).
|
|
func IsSupportedCLIVersion(version string) bool {
|
|
canonical := "v" + version
|
|
minimum := "v" + CLIStableVersion
|
|
return semver.IsValid(canonical) &&
|
|
semver.Canonical(canonical) == canonical &&
|
|
semver.Compare(canonical, minimum) >= 0
|
|
}
|
|
|
|
// CLIUserAgent 对齐官方交互式 CLI 的 UA,平台名称使用 Rust 的格式。
|
|
func CLIUserAgent(version string) string {
|
|
if strings.TrimSpace(version) == "" {
|
|
version = CLIClientVersion
|
|
}
|
|
platform, arch := runtime.GOOS, runtime.GOARCH
|
|
if platform == "darwin" {
|
|
platform = "macos"
|
|
}
|
|
switch arch {
|
|
case "amd64":
|
|
arch = "x86_64"
|
|
case "arm64":
|
|
arch = "aarch64"
|
|
case "386":
|
|
arch = "x86"
|
|
}
|
|
return "grok-pager/" + version + " grok-shell/" + version + " (" + platform + "; " + arch + ")"
|
|
}
|
|
|
|
// ApplyCLIProxyHeaders stamps the fixed Grok CLI identity when the request
|
|
// targets cli-chat-proxy. Direct api.x.ai traffic is left unchanged.
|
|
func ApplyCLIProxyHeaders(req *http.Request) {
|
|
if req == nil || req.URL == nil || !strings.EqualFold(strings.TrimSpace(req.URL.Hostname()), CLIProxyHost) {
|
|
return
|
|
}
|
|
if req.Header == nil {
|
|
req.Header = make(http.Header)
|
|
}
|
|
version := ResolveCLIVersion()
|
|
req.Header.Set("X-XAI-Token-Auth", CLITokenAuth)
|
|
req.Header.Set("x-grok-client-version", version)
|
|
req.Header.Set("x-grok-client-identifier", CLIClientIdentifier)
|
|
req.Header.Set("x-grok-client-mode", CLIClientMode)
|
|
req.Header.Set("x-authenticateresponse", "authenticate-response")
|
|
req.Header.Set("User-Agent", CLIUserAgent(version))
|
|
}
|