Antigravity: - UA: 固定 darwin/arm64(不用 runtime),匹配真实 macOS 桌面用户 - x-goog-api-client: 硬编码 go1.27(不用 runtime.Version()) - 环境变量 ANTIGRAVITY_PLATFORM_OS/ARCH 可覆盖 Gemini CLI: - UA: 固定 darwin/arm64(Node.js process.platform/arch 格式) - 注意: Node.js 用 x64 不是 amd64,arm64 两者一致 - 环境变量 GEMINI_CLI_PLATFORM_OS/ARCH 可覆盖 删除 runtime 包依赖,所有平台标识改为可配置的硬编码默认值。
120 lines
5.3 KiB
Go
120 lines
5.3 KiB
Go
// Package geminicli provides helpers for interacting with Gemini CLI tools.
|
||
package geminicli
|
||
|
||
import (
|
||
"fmt"
|
||
"os"
|
||
"time"
|
||
)
|
||
|
||
const (
|
||
AIStudioBaseURL = "https://generativelanguage.googleapis.com"
|
||
GeminiCliBaseURL = "https://cloudcode-pa.googleapis.com"
|
||
|
||
AuthorizeURL = "https://accounts.google.com/o/oauth2/v2/auth"
|
||
TokenURL = "https://oauth2.googleapis.com/token"
|
||
|
||
// AIStudioOAuthRedirectURI is the default redirect URI used for AI Studio OAuth.
|
||
// This matches the "copy/paste callback URL" flow used by OpenAI OAuth in this project.
|
||
// Note: You still need to register this redirect URI in your Google OAuth client
|
||
// unless you use an OAuth client type that permits localhost redirect URIs.
|
||
AIStudioOAuthRedirectURI = "http://localhost:1455/auth/callback"
|
||
|
||
// DefaultScopes for Code Assist (includes cloud-platform for API access plus userinfo scopes)
|
||
// Required by Google's Code Assist API.
|
||
DefaultCodeAssistScopes = "https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile"
|
||
|
||
// DefaultScopes for AI Studio (uses generativelanguage API with OAuth)
|
||
// Reference: https://ai.google.dev/gemini-api/docs/oauth
|
||
// For regular Google accounts, supports API calls to generativelanguage.googleapis.com
|
||
// Note: Google Auth platform currently documents the OAuth scope as
|
||
// https://www.googleapis.com/auth/generative-language.retriever (often with cloud-platform).
|
||
DefaultAIStudioScopes = "https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/generative-language.retriever"
|
||
|
||
// DefaultGoogleOneScopes (DEPRECATED, no longer used)
|
||
// Google One now always uses the built-in Gemini CLI client with DefaultCodeAssistScopes.
|
||
// This constant is kept for backward compatibility but is not actively used.
|
||
DefaultGoogleOneScopes = "https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/generative-language.retriever https://www.googleapis.com/auth/drive.readonly https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile"
|
||
|
||
// GeminiCLIRedirectURI is the redirect URI used by Gemini CLI for Code Assist OAuth.
|
||
GeminiCLIRedirectURI = "https://codeassist.google.com/authcode"
|
||
|
||
// GeminiCLIOAuthClientID/Secret are the public OAuth client credentials used by Google Gemini CLI.
|
||
// They enable the "login without creating your own OAuth client" experience, but Google may
|
||
// restrict which scopes are allowed for this client.
|
||
GeminiCLIOAuthClientID = "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com"
|
||
GeminiCLIOAuthClientSecret = "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"
|
||
|
||
// GeminiCLIOAuthClientSecretEnv is the environment variable name for the built-in client secret.
|
||
GeminiCLIOAuthClientSecretEnv = "GEMINI_CLI_OAUTH_CLIENT_SECRET"
|
||
|
||
SessionTTL = 30 * time.Minute
|
||
|
||
// GeminiCLIUserAgent 静态回退值(不含 model)
|
||
// 优先使用 GetGeminiCLIUserAgent(model) 获取完整格式
|
||
GeminiCLIUserAgent = "GeminiCLI/0.33.1"
|
||
|
||
// FakeNodeVersion 模拟真实 Gemini CLI 的 Node.js 版本
|
||
// 用于 x-goog-api-client 和 token exchange User-Agent
|
||
FakeNodeVersion = "24.13.1"
|
||
|
||
// 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, defaultFakePlatformOS, defaultFakePlatformArch)
|
||
}
|
||
|
||
// GetGeminiCLIGoogAPIClient 返回 x-goog-api-client 头的值
|
||
// 真实 Gemini CLI 通过 google-auth-library DefaultTransporter 自动注入:
|
||
// gl-node/{nodeVersion}
|
||
func GetGeminiCLIGoogAPIClient() string {
|
||
return fmt.Sprintf("gl-node/%s", FakeNodeVersion)
|
||
}
|
||
|
||
// GetGeminiCLITokenExchangeUA 返回 token exchange/refresh 时的 User-Agent
|
||
// 真实 Gemini CLI 使用 google-auth-library 发起 token 交换
|
||
func GetGeminiCLITokenExchangeUA() string {
|
||
return GoogleAuthLibraryUA
|
||
}
|