// 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 }