Documentation
¶
Index ¶
- Constants
- Variables
- func GrokExpiryUnix(now, expiresIn int64) (int64, error)
- func OpenBrowser(url string) error
- func ValidGrokAccountID(accountID string) bool
- func ValidateGrokDeviceCodeForDisplay(device *GrokDeviceCode) error
- type ChatGPTCredentials
- type ChatGPTDeviceCode
- type ChatGPTTokenResponse
- type CopilotCredentials
- type CopilotDeviceCodeResponse
- type CopilotTokenResponse
- type GrokDeviceCode
- type GrokOAuthClient
- func (c *GrokOAuthClient) PollDeviceToken(ctx context.Context, device *GrokDeviceCode) (*GrokTokenResponse, error)
- func (c *GrokOAuthClient) RefreshToken(ctx context.Context, refreshToken string) (*GrokTokenResponse, error)
- func (c *GrokOAuthClient) RequestDeviceCode(ctx context.Context) (*GrokDeviceCode, error)
- func (c *GrokOAuthClient) Revoke(ctx context.Context, token string) error
- func (c *GrokOAuthClient) UserInfo(ctx context.Context, accessToken string) (string, error)
- type GrokTokenResponse
Constants ¶
const ( ChatGPTAuthEndpoint = "https://auth.openai.com/oauth/authorize" ChatGPTTokenEndpoint = "https://auth.openai.com/oauth/token" // Temporary until we figure out how term-llm can get a proper client ID ChatGPTClientID = "app_EMoamEEZ73f0CkXaXp7hrann" ChatGPTRedirectURI = "http://localhost:1455/auth/callback" ChatGPTScopes = "openid profile email offline_access" ChatGPTCallbackPort = 1455 )
const ( ChatGPTDeviceAuthBaseURL = "https://auth.openai.com/api/accounts" ChatGPTDeviceVerificationURL = "https://auth.openai.com/codex/device" ChatGPTDeviceRedirectURI = "https://auth.openai.com/deviceauth/callback" )
The device code flow talks to OpenAI's /deviceauth endpoints. It is the same flow codex uses for headless/remote sign-in — no local callback server, no browser redirect to localhost, just a URL + code the user visits on any device.
const ( // CopilotClientID is the VS Code GitHub Copilot extension's client ID. // This is required for access to GitHub's internal Copilot APIs (usage, token exchange). // Using the VS Code client ID is a common approach in the Copilot developer community. CopilotClientID = "Iv1.b507a08c87ecfe98" // CopilotScope is the OAuth scope required for Copilot API access CopilotScope = "read:user" )
const ( GrokClientID = "b1a00492-073a-47ea-816f-4c329264a828" // term-llm only calls the subscription Responses and model-catalog APIs, so // conversations/workspaces scopes from grok-build are intentionally omitted. GrokScopes = "openid profile email offline_access grok-cli:access api:access" GrokDeviceEndpoint = "https://auth.x.ai/oauth2/device/code" GrokTokenEndpoint = "https://auth.x.ai/oauth2/token" GrokUserInfoEndpoint = "https://auth.x.ai/oauth2/userinfo" GrokRevokeEndpoint = "https://auth.x.ai/oauth2/revoke" )
Variables ¶
var ( ErrGrokAccessDenied = errors.New("Grok authorization was denied") ErrGrokDeviceCodeExpired = errors.New("Grok device authorization expired") ErrGrokRefreshTokenInvalid = errors.New("Grok refresh token expired or revoked") )
var ErrChatGPTDeviceCodeNotEnabled = errors.New("chatgpt device code login is not enabled")
ErrChatGPTDeviceCodeNotEnabled is returned when the backend does not advertise device-code login (HTTP 404). Callers should fall back to the interactive browser flow.
var ErrChatGPTRefreshTokenInvalid = errors.New("ChatGPT refresh token expired or revoked")
ErrChatGPTRefreshTokenInvalid indicates that the authorization server has definitively rejected a refresh token, rather than a transient refresh error.
Functions ¶
func GrokExpiryUnix ¶ added in v0.0.404
func OpenBrowser ¶ added in v0.9.11
OpenBrowser opens a URL in the user's default browser.
func ValidGrokAccountID ¶ added in v0.0.404
ValidGrokAccountID accepts only bounded visible ASCII so userinfo.sub is safe to copy into x-grok-user-id/x-userid headers.
func ValidateGrokDeviceCodeForDisplay ¶ added in v0.0.404
func ValidateGrokDeviceCodeForDisplay(device *GrokDeviceCode) error
ValidateGrokDeviceCodeForDisplay ensures device-flow values are safe to render in a terminal and that verification URLs remain on x.ai-owned HTTPS hosts.
Types ¶
type ChatGPTCredentials ¶
type ChatGPTCredentials struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
ExpiresAt int64 `json:"expires_at"` // Unix timestamp in seconds
AccountID string `json:"account_id"` // ChatGPT account ID from JWT
}
ChatGPTCredentials holds the OAuth tokens
func AuthenticateChatGPT ¶
func AuthenticateChatGPT(ctx context.Context) (*ChatGPTCredentials, error)
AuthenticateChatGPT runs the full OAuth flow and returns credentials
func AuthenticateChatGPTDevice ¶ added in v0.0.170
func AuthenticateChatGPTDevice(ctx context.Context, dc *ChatGPTDeviceCode) (*ChatGPTCredentials, error)
AuthenticateChatGPTDevice runs the full device-code OAuth flow. The caller is responsible for printing the verification URL + user code between RequestChatGPTDeviceCode and this call — taking a callback here keeps the prompt UX out of the oauth package.
func (*ChatGPTCredentials) IsExpired ¶
func (c *ChatGPTCredentials) IsExpired() bool
IsExpired returns true if the access token is expired or will expire within 5 minutes
type ChatGPTDeviceCode ¶ added in v0.0.170
type ChatGPTDeviceCode struct {
VerificationURL string
UserCode string
// contains filtered or unexported fields
}
ChatGPTDeviceCode is the user-facing output of the usercode request.
func RequestChatGPTDeviceCode ¶ added in v0.0.170
func RequestChatGPTDeviceCode(ctx context.Context) (*ChatGPTDeviceCode, error)
RequestChatGPTDeviceCode asks OpenAI for a new device-auth pair. Returns ErrChatGPTDeviceCodeNotEnabled when the server returns 404.
type ChatGPTTokenResponse ¶
type ChatGPTTokenResponse struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
IDToken string `json:"id_token"`
ExpiresIn int `json:"expires_in"`
TokenType string `json:"token_type"`
}
func RefreshToken ¶
func RefreshToken(refreshToken string) (*ChatGPTTokenResponse, error)
RefreshToken refreshes an expired access token
type CopilotCredentials ¶ added in v0.0.34
type CopilotCredentials struct {
AccessToken string `json:"access_token"`
ExpiresAt int64 `json:"expires_at"` // 0 = no expiry tracking
}
CopilotCredentials holds the OAuth token for Copilot. Note: credentials.CopilotCredentials is the storage type with the same fields.
func AuthenticateCopilot ¶ added in v0.0.34
func AuthenticateCopilot(ctx context.Context) (*CopilotCredentials, error)
AuthenticateCopilot runs the full device code OAuth flow and returns credentials
type CopilotDeviceCodeResponse ¶ added in v0.0.34
type CopilotDeviceCodeResponse struct {
DeviceCode string `json:"device_code"`
UserCode string `json:"user_code"`
VerificationURI string `json:"verification_uri"`
ExpiresIn int `json:"expires_in"`
Interval int `json:"interval"` // Polling interval in seconds
}
CopilotDeviceCodeResponse holds the device code response from GitHub
func RequestCopilotDeviceCode ¶ added in v0.0.34
func RequestCopilotDeviceCode() (*CopilotDeviceCodeResponse, error)
RequestCopilotDeviceCode initiates the device code flow
type CopilotTokenResponse ¶ added in v0.0.34
type CopilotTokenResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
Scope string `json:"scope"`
Error string `json:"error,omitempty"`
}
CopilotTokenResponse holds the token response from GitHub
func PollForCopilotToken ¶ added in v0.0.34
func PollForCopilotToken(ctx context.Context, deviceCode string, interval int) (*CopilotTokenResponse, error)
PollForCopilotToken polls for the access token after the user has authorized
type GrokDeviceCode ¶ added in v0.0.404
type GrokOAuthClient ¶ added in v0.0.404
GrokOAuthClient implements xAI's RFC 8628 device flow. Endpoint replacement is intentionally private; tests inject a transport that rewrites production URLs.
func NewGrokOAuthClient ¶ added in v0.0.404
func NewGrokOAuthClient(httpClient *http.Client) *GrokOAuthClient
func (*GrokOAuthClient) PollDeviceToken ¶ added in v0.0.404
func (c *GrokOAuthClient) PollDeviceToken(ctx context.Context, device *GrokDeviceCode) (*GrokTokenResponse, error)
func (*GrokOAuthClient) RefreshToken ¶ added in v0.0.404
func (c *GrokOAuthClient) RefreshToken(ctx context.Context, refreshToken string) (*GrokTokenResponse, error)
func (*GrokOAuthClient) RequestDeviceCode ¶ added in v0.0.404
func (c *GrokOAuthClient) RequestDeviceCode(ctx context.Context) (*GrokDeviceCode, error)