diff --git a/backend/internal/pkg/antigravity/client.go b/backend/internal/pkg/antigravity/client.go index a278acd1..be4df02e 100644 --- a/backend/internal/pkg/antigravity/client.go +++ b/backend/internal/pkg/antigravity/client.go @@ -12,7 +12,6 @@ import ( "net" "net/http" "net/url" - "runtime" "strings" "time" @@ -32,9 +31,9 @@ func (e *ForbiddenError) Error() string { // GetGoogAPIClient 返回 x-goog-api-client 头的值(导出供心跳等外部使用) // 格式与真实 Antigravity 的 Go SDK 一致: gl-go/{goVersion} gax-go/v2 grpc-go/1.81.0-dev +// 注意: 不使用 runtime.Version() — 服务器编译的 Go 版本 ≠ 真实 Antigravity 的 Go 版本 func GetGoogAPIClient() string { - goVer := runtime.Version() // e.g. "go1.22.0" - return fmt.Sprintf("gl-go/%s gax-go/v2 grpc-go/1.81.0-dev", goVer) + return "gl-go/go1.27 gax-go/v2 grpc-go/1.81.0-dev" } // setAntigravityHeaders 设置与真实 Antigravity IDE 一致的 HTTP 请求头 diff --git a/backend/internal/pkg/antigravity/oauth.go b/backend/internal/pkg/antigravity/oauth.go index fdecbe92..cbcbf664 100644 --- a/backend/internal/pkg/antigravity/oauth.go +++ b/backend/internal/pkg/antigravity/oauth.go @@ -9,7 +9,6 @@ import ( "net/http" "net/url" "os" - "runtime" "strings" "sync" "time" @@ -56,6 +55,14 @@ const ( // defaultUserAgentVersion 可通过环境变量 ANTIGRAVITY_USER_AGENT_VERSION 配置,默认 0.2.0(匹配真实 extension 版本) var defaultUserAgentVersion = "0.2.0" +// defaultPlatformOS 和 defaultPlatformArch 模拟真实客户端的操作系统和架构 +// 真实 Antigravity IDE 运行在用户桌面(macOS/Windows),不是 Linux 服务器 +// 可通过环境变量 ANTIGRAVITY_PLATFORM_OS / ANTIGRAVITY_PLATFORM_ARCH 覆盖 +var ( + defaultPlatformOS = "darwin" + defaultPlatformArch = "arm64" +) + // defaultClientSecret 可通过环境变量 ANTIGRAVITY_OAUTH_CLIENT_SECRET 配置 var defaultClientSecret = "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" @@ -68,13 +75,19 @@ func init() { if secret := os.Getenv(AntigravityOAuthClientSecretEnv); secret != "" { defaultClientSecret = secret } + // 从环境变量读取模拟平台(真实 Antigravity 运行在桌面 OS,不是 Linux 服务器) + if p := os.Getenv("ANTIGRAVITY_PLATFORM_OS"); p != "" { + defaultPlatformOS = p + } + if a := os.Getenv("ANTIGRAVITY_PLATFORM_ARCH"); a != "" { + defaultPlatformArch = a + } } // GetUserAgent 返回当前配置的 User-Agent(匹配真实 Antigravity 格式: antigravity/{version} {os}/{arch}) +// 注意: 不使用 runtime.GOOS/GOARCH — 服务器是 Linux,但真实用户在 macOS/Windows 桌面 func GetUserAgent() string { - osName := runtime.GOOS // darwin, linux, windows - arch := runtime.GOARCH // arm64, amd64 - return fmt.Sprintf("antigravity/%s %s/%s", defaultUserAgentVersion, osName, arch) + return fmt.Sprintf("antigravity/%s %s/%s", defaultUserAgentVersion, defaultPlatformOS, defaultPlatformArch) } func getClientSecret() (string, error) { diff --git a/backend/internal/pkg/geminicli/constants.go b/backend/internal/pkg/geminicli/constants.go index 19a3ddd9..a79fde6a 100644 --- a/backend/internal/pkg/geminicli/constants.go +++ b/backend/internal/pkg/geminicli/constants.go @@ -4,7 +4,6 @@ package geminicli import ( "fmt" "os" - "runtime" "time" ) @@ -62,27 +61,48 @@ const ( // GoogleAuthLibraryUA 模拟 google-auth-library 的 User-Agent // 真实 Gemini CLI token exchange 由 google-auth-library 发起 GoogleAuthLibraryUA = "google-api-nodejs-client" + + // FakePlatformOS 和 FakePlatformArch 模拟真实客户端的操作系统和架构 + // 真实 Gemini CLI 运行在用户桌面,不是 Linux 服务器 + // Node.js process.platform: darwin, linux, win32 + // Node.js process.arch: arm64, x64 (注意: Node.js 用 x64,不是 amd64) + FakePlatformOS = "darwin" + FakePlatformArch = "arm64" ) // defaultGeminiCLIVersion 可通过环境变量 GEMINI_CLI_VERSION 覆盖 var defaultGeminiCLIVersion = "0.33.1" +// defaultFakePlatformOS/Arch 可通过环境变量覆盖 +var ( + defaultFakePlatformOS = FakePlatformOS + defaultFakePlatformArch = FakePlatformArch +) + func init() { if v := os.Getenv("GEMINI_CLI_VERSION"); v != "" { defaultGeminiCLIVersion = v } + if p := os.Getenv("GEMINI_CLI_PLATFORM_OS"); p != "" { + defaultFakePlatformOS = p + } + if a := os.Getenv("GEMINI_CLI_PLATFORM_ARCH"); a != "" { + defaultFakePlatformArch = a + } } // GetGeminiCLIUserAgent 返回匹配真实 Gemini CLI 格式的 User-Agent // 真实格式: GeminiCLI/{version}/{model} ({platform}; {arch}) // 示例: GeminiCLI/0.33.1/gemini-2.5-pro (darwin; arm64) +// 注意: 不使用 runtime.GOOS/GOARCH — 服务器是 Linux,但要模拟桌面客户端 +// 注意: Node.js 用 x64 不是 amd64,arm64 两者一致 func GetGeminiCLIUserAgent(model ...string) string { m := "unknown" if len(model) > 0 && model[0] != "" { m = model[0] } return fmt.Sprintf("GeminiCLI/%s/%s (%s; %s)", - defaultGeminiCLIVersion, m, runtime.GOOS, runtime.GOARCH) + defaultGeminiCLIVersion, m, defaultFakePlatformOS, defaultFakePlatformArch) } // GetGeminiCLIGoogAPIClient 返回 x-goog-api-client 头的值