Help us shape the future of Go! Take the 2026 Go Developer Survey

openaisubscription

package
v0.16.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 2, 2026 License: Apache-2.0 Imports: 44 Imported by: 0

Documentation

Overview

Package openaisubscription provides inference authorized against a user's ChatGPT plan through the public Sign in with ChatGPT contract.

Index

Constants

View Source
const (
	Issuer           = "https://auth.openai.com"
	AuthorizationURL = Issuer + "/api/accounts/authorize"
	TokenURL         = Issuer + "/api/accounts/oauth/token"
	JWKSURL          = Issuer + "/.well-known/jwks.json"
	DiscoveryURL     = Issuer + "/.well-known/openid-configuration"
)
View Source
const BaseURL = "https://api.openai.com/v1"

Variables

View Source
var (
	ErrLogin      = errors.New("openai-subscription: sign-in failed; retry login")
	ErrIdentity   = errors.New("openai-subscription: identity verification failed")
	ErrPermission = errors.New("openai-subscription: ChatGPT plan usage permission is required; sign in again and allow plan usage")
	ErrToken      = errors.New("openai-subscription: token exchange failed; sign in again")
	// ErrTokenUnavailable is a token-endpoint failure that did not consume the
	// grant (a connection that never sent the request, throttling or a server
	// error). Credentials are preserved; retry with bounded backoff.
	ErrTokenUnavailable = errors.New("openai-subscription: token endpoint temporarily unavailable; retry later")
	// ErrTokenUncertain is a refresh whose request may have reached OpenAI but
	// whose response was lost or unusable. The refresh token may already be
	// rotated, so it is never submitted again; sign in again.
	ErrTokenUncertain = errors.New("openai-subscription: token refresh outcome unknown; sign in again")
	// ErrClient is invalid_client: the saved client registration was
	// rejected. Retrying or refreshing cannot fix it.
	ErrClient = errors.New("openai-subscription: OAuth client registration rejected; check the saved client or sign in again")
	ErrModels = errors.New("openai-subscription: could not retrieve account models")
	ErrRevoke = errors.New("openai-subscription: remote revocation was not confirmed; disconnect Carbon in ChatGPT settings")
)
View Source
var ErrUsageLimit = errors.New("openai-subscription: ChatGPT plan usage limit reached; see ChatGPT Settings > Usage")

ErrUsageLimit reports that the ChatGPT plan, or this app's limit on it, is exhausted. OpenAI's recovery is to pause requests that use the plan and point the user at ChatGPT Settings > Usage; it is not rate pressure and must not be retried.

Functions

func NewHostID

func NewHostID() (string, error)

func NewSource

NewSource adapts provider-owned continuity to the existing coordinated, versioned refresh machinery. The coordinator must cover the state store.

func Revoke

func Revoke(ctx context.Context, client *http.Client, state refresh.State) error

Revoke ends this renewable session using the issuer's discovery document. A local deletion is separate from confirmed remote revocation.

Types

type AvailableModel

type AvailableModel struct {
	Slug        string `json:"slug"`
	DisplayName string `json:"display_name"`
}

func ListModels

func ListModels(ctx context.Context, source credentials.Source, client *http.Client) ([]AvailableModel, error)

ListModels returns the current selected account's displayable models in server order. Catalog inclusion is not proof an inference request will succeed.

type Client

type Client struct{ *transport.Client }

Client supports call-scoped authorization. Construct through auto.NewWithAuth to bind an OAuth subscription Source to it; no credential is read implicitly.

func New

func New(selected model.Model, options ...Option) (*Client, error)

func (*Client) Invoke

func (c *Client) Invoke(ctx context.Context, req inference.Request) (*inference.Response, error)

Invoke collects the same mandatory streaming wire flow used by Stream.

func (*Client) InvokeWithAuth

func (c *Client) InvokeWithAuth(ctx context.Context, req inference.Request, auth httpauth.Authorizer) (*inference.Response, error)

func (*Client) InvokeWithAuthorizer

func (c *Client) InvokeWithAuthorizer(ctx context.Context, req inference.Request, auth httpauth.Authorizer) (*inference.Response, error)

InvokeWithAuthorizer is a descriptive alias for InvokeWithAuth. It is declared here so the promoted transport alias cannot bypass the mandatory streaming flow.

func (*Client) Stream

Stream sends one streaming request with the client's default authorizer.

func (*Client) StreamWithAuth

StreamWithAuth sends one streaming request with a call-scoped authorizer.

func (*Client) StreamWithAuthorizer

func (c *Client) StreamWithAuthorizer(ctx context.Context, req inference.Request, auth httpauth.Authorizer) (*stream.StreamReader[content.Chunk], error)

StreamWithAuthorizer is a descriptive alias for StreamWithAuth.

type IncompleteError

type IncompleteError struct{ Reason string }

IncompleteError reports response.incomplete. OpenAI documents only response.completed as successful inference, so partial output is never returned as a result. Reason is the bounded incomplete_details.reason (e.g. max_output_tokens, content_filter) when present.

func (*IncompleteError) Error

func (e *IncompleteError) Error() string

type LoginOptions

type LoginOptions struct {
	HostID      string
	Previous    *Registration
	OpenBrowser func(string) error
	HTTPClient  *http.Client
}

type Option

type Option func(*config)

func WithRoundTripper

func WithRoundTripper(rt http.RoundTripper) Option

func WithTLSRootCAs

func WithTLSRootCAs(roots *x509.CertPool) Option

type Registration

type Registration struct {
	ClientID string `json:"client_id"`
	Subject  string `json:"subject"`
	Email    string `json:"email,omitempty"`
	HostID   string `json:"host_id"`
	IDToken  string `json:"id_token,omitempty"`
	Scopes   string `json:"scopes,omitempty"`
}

Registration is private account continuity, never display metadata. Persist it only in protected state. Formatting and logging deliberately redact it.

func Login

func Login(ctx context.Context, options LoginOptions) (refresh.State, Registration, error)

Login runs a bounded browser flow with a stable callback path. It leaves all local persistence to the caller and never mutates a selected account on failure.

func RegistrationFromState

func RegistrationFromState(state refresh.State) (Registration, error)

func (Registration) AccountName

func (r Registration) AccountName() string

AccountName is a stable non-identifying local label, distinct per client and account.

func (Registration) Format

func (r Registration) Format(s fmt.State, _ rune)

func (Registration) LogValue

func (r Registration) LogValue() slog.Value

func (Registration) String

func (r Registration) String() string

func (Registration) Validate

func (r Registration) Validate() error

type ResponseError

type ResponseError struct{ Code, Param string }

ResponseError is a Responses failure (response.failed or a top-level error event) after the stream opened. Only bounded code tokens are kept: the provider's free-form message is never retained, so it cannot carry request text or credentials into logs. Param names the rejected input when the provider reports one (e.g. subscription_sharing_unsupported_capability).

func (*ResponseError) Error

func (e *ResponseError) Error() string

func (*ResponseError) Format

func (e *ResponseError) Format(s fmt.State, _ rune)

func (*ResponseError) GoString

func (e *ResponseError) GoString() string

type UsageLimitError

type UsageLimitError struct{ RequestID string }

UsageLimitError is ErrUsageLimit with the bounded request ID when one was returned. It is deliberately not a *failure.APIError, so generic retry policies (which retry every HTTP 429) do not retry it.

func (*UsageLimitError) Error

func (e *UsageLimitError) Error() string

func (*UsageLimitError) Unwrap

func (e *UsageLimitError) Unwrap() error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL