Documentation
¶
Overview ¶
Package copilot implements the GitHub Copilot Provider.
Copilot's chat endpoint is reverse-engineered from public clients (copilot.vim, copilot-language-server). The wire shape is OpenAI-compatible Chat Completions; the auth flow is the distinguishing piece:
- Device-code OAuth against github.com → user-facing code
- Poll for GH access token
- Exchange GH token at api.github.com/copilot_internal/v2/token for a short-lived Copilot internal token (refresh via the same endpoint when it expires)
- Use the Copilot token against api.githubcopilot.com with Editor-Version + Copilot-Integration-Id headers
The exchange response includes `endpoints.api` which we respect — GitHub has moved this for some users.
Package copilot will implement the GitHub Copilot Provider.
Lands in v0.2 (NOT v0.1). Copilot's chat endpoint is reverse-engineered, not a documented public API, so the adapter carries its own brittleness budget. When v0.2 ships:
- OAuth device-code flow against GitHub
- Token exchange to a short-lived Copilot internal token (refresh transparently; honor `endpoints.api` in the exchange response)
- Required headers: Editor-Version, Copilot-Integration-Id (a known-good ID is required; the whitelist is server-side)
- Streaming response shape differs subtly from official OpenAI
- Failover: Copilot 401 → OpenRouter with same model name (pre-wired)
Until then this package is intentionally empty; the architecture doc commits to the surface at § Providers → v0.2 — GitHub Copilot.
Index ¶
- Constants
- Variables
- func FinishDeviceFlow(ctx context.Context, clientID string, dc *DeviceCode) (string, error)
- type DeviceCode
- type Provider
- func (p *Provider) Chat(ctx context.Context, req *provider.Request) (<-chan provider.StreamEvent, error)
- func (p *Provider) Models(ctx context.Context) ([]provider.Model, error)
- func (p *Provider) Name() string
- func (p *Provider) TokenCount(_ context.Context, _ string, msgs []provider.Message) (int, error)
Constants ¶
const (
// DefaultClientID is the public Copilot OAuth client ID.
DefaultClientID = "Iv1.b507a08c87ecfe98"
)
Variables ¶
var (
ErrNoGHToken = errors.New("copilot: GitHub access token not set; run device-flow auth first")
)
Errors.
Functions ¶
func FinishDeviceFlow ¶
FinishDeviceFlow polls until the user completes the GitHub authorization. Returns the GitHub access token.
Types ¶
type DeviceCode ¶
type DeviceCode 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"`
}
DeviceCode is the response from POST /login/device/code.
func StartDeviceFlow ¶
func StartDeviceFlow(ctx context.Context, clientID string) (*DeviceCode, error)
StartDeviceFlow begins a device-code OAuth flow against GitHub. Returns the codes; the caller displays UserCode + VerificationURI to the user and then polls FinishDeviceFlow.
type Provider ¶
type Provider struct {
// GHToken is the GitHub access token obtained via device-code
// OAuth. Stored in credstore under (provider="copilot",
// account="github"); the harness loads it before calling Chat.
GHToken string
// IntegrationID overrides the default ("vscode-chat"). Other
// known-good values: "vscode" / "copilot-chat" / "jetbrains".
IntegrationID string
// EditorVersion is the User-Agent-like string Copilot expects.
EditorVersion string
HTTP *http.Client
// contains filtered or unexported fields
}
Provider is the GitHub Copilot Provider.
func (*Provider) Chat ¶
func (p *Provider) Chat(ctx context.Context, req *provider.Request) (<-chan provider.StreamEvent, error)
Chat implements provider.Provider.