Record agentic invocations in User-Agent header
Detect which AI coding agent is invoking gh by checking well-known environment variables and include the agent name in the User-Agent header sent to GitHub APIs. Supported agents: Codex, Gemini CLI, Copilot CLI, OpenCode, Claude Code, and Amp. Generic AI_AGENT env var is also supported with validation to prevent header injection. Fixes github/cli#1111 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
8723e3bb52
commit
c51769c977
10 changed files with 311 additions and 41 deletions
|
|
@ -15,7 +15,6 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
accept = "Accept"
|
||||
apiVersion = "X-GitHub-Api-Version"
|
||||
apiVersionValue = "2022-11-28"
|
||||
authorization = "Authorization"
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ type tokenGetter interface {
|
|||
|
||||
type HTTPClientOptions struct {
|
||||
AppVersion string
|
||||
InvokingAgent string
|
||||
CacheTTL time.Duration
|
||||
Config tokenGetter
|
||||
EnableCache bool
|
||||
|
|
@ -48,8 +49,13 @@ func NewHTTPClient(opts HTTPClientOptions) (*http.Client, error) {
|
|||
clientOpts.LogVerboseHTTP = opts.LogVerboseHTTP
|
||||
}
|
||||
|
||||
ua := fmt.Sprintf("GitHub CLI %s", opts.AppVersion)
|
||||
if opts.InvokingAgent != "" {
|
||||
ua = fmt.Sprintf("%s Agent/%s", ua, opts.InvokingAgent)
|
||||
}
|
||||
|
||||
headers := map[string]string{
|
||||
userAgent: fmt.Sprintf("GitHub CLI %s", opts.AppVersion),
|
||||
userAgent: ua,
|
||||
apiVersion: apiVersionValue,
|
||||
}
|
||||
clientOpts.Headers = headers
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ func TestNewHTTPClient(t *testing.T) {
|
|||
type args struct {
|
||||
config tokenGetter
|
||||
appVersion string
|
||||
invokingAgent string
|
||||
logVerboseHTTP bool
|
||||
skipDefaultHeaders bool
|
||||
}
|
||||
|
|
@ -155,6 +156,18 @@ func TestNewHTTPClient(t *testing.T) {
|
|||
* Request took <duration>
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "includes invoking agent in user-agent header",
|
||||
args: args{
|
||||
appVersion: "v1.2.3",
|
||||
invokingAgent: "copilot-cli",
|
||||
},
|
||||
host: "github.com",
|
||||
wantHeader: map[string][]string{
|
||||
"user-agent": {"GitHub CLI v1.2.3 Agent/copilot-cli"},
|
||||
},
|
||||
wantStderr: "",
|
||||
},
|
||||
}
|
||||
|
||||
var gotReq *http.Request
|
||||
|
|
@ -169,6 +182,7 @@ func TestNewHTTPClient(t *testing.T) {
|
|||
ios, _, _, stderr := iostreams.Test()
|
||||
client, err := NewHTTPClient(HTTPClientOptions{
|
||||
AppVersion: tt.args.appVersion,
|
||||
InvokingAgent: tt.args.invokingAgent,
|
||||
Config: tt.args.config,
|
||||
Log: ios.ErrOut,
|
||||
LogVerboseHTTP: tt.args.logVerboseHTTP,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue