Skip to content

Commit

Permalink
feat: Support Copilot metrics endpoints (#3350)
Browse files Browse the repository at this point in the history
  • Loading branch information
henriklundstrom authored Nov 20, 2024
1 parent 6d30edd commit 717e93f
Show file tree
Hide file tree
Showing 4 changed files with 1,811 additions and 0 deletions.
223 changes: 223 additions & 0 deletions github/copilot.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,125 @@ type CopilotUsageSummary struct {
Breakdown []*CopilotUsageBreakdown `json:"breakdown"`
}

// CopilotMetricsListOptions represents the optional parameters to the CopilotService get metrics methods.
type CopilotMetricsListOptions struct {
Since *time.Time `url:"since,omitempty"`
Until *time.Time `url:"until,omitempty"`

ListOptions
}

// CopilotIDECodeCompletionsLanguage represents Copilot usage metrics for completions in the IDE for a language.
type CopilotIDECodeCompletionsLanguage struct {
Name string `json:"name"`
TotalEngagedUsers int `json:"total_engaged_users"`
}

// CopilotIDECodeCompletionsModelLanguage represents Copilot usage metrics for completions in the IDE for a model and language.
type CopilotIDECodeCompletionsModelLanguage struct {
Name string `json:"name"`
TotalEngagedUsers int `json:"total_engaged_users"`
TotalCodeSuggestions int `json:"total_code_suggestions"`
TotalCodeAcceptances int `json:"total_code_acceptances"`
TotalCodeLinesSuggested int `json:"total_code_lines_suggested"`
TotalCodeLinesAccepted int `json:"total_code_lines_accepted"`
}

// CopilotIDECodeCompletionsModel represents Copilot usage metrics for completions in the IDE for a model.
type CopilotIDECodeCompletionsModel struct {
Name string `json:"name"`
IsCustomModel bool `json:"is_custom_model"`
CustomModelTrainingDate *string `json:"custom_model_training_date,omitempty"`
TotalEngagedUsers int `json:"total_engaged_users"`
Languages []*CopilotIDECodeCompletionsModelLanguage `json:"languages"`
}

// CopilotIDECodeCompletionsEditor represents Copilot usage metrics for completions in the IDE for an editor.
type CopilotIDECodeCompletionsEditor struct {
Name string `json:"name"`
TotalEngagedUsers int `json:"total_engaged_users"`
Models []*CopilotIDECodeCompletionsModel `json:"models"`
}

// CopilotIDECodeCompletions represents Copilot usage metrics for Copilot code completions in the IDE, categorized by editor, model and language.
type CopilotIDECodeCompletions struct {
TotalEngagedUsers int `json:"total_engaged_users"`
Languages []*CopilotIDECodeCompletionsLanguage `json:"languages"`
Editors []*CopilotIDECodeCompletionsEditor `json:"editors"`
}

// CopilotIDEChatModel represents Copilot usage metrics for chatting with a model in the IDE.
type CopilotIDEChatModel struct {
Name string `json:"name"`
IsCustomModel bool `json:"is_custom_model"`
CustomModelTrainingDate *string `json:"custom_model_training_date,omitempty"`
TotalEngagedUsers int `json:"total_engaged_users"`
TotalChats int `json:"total_chats"`
TotalChatInsertionEvents int `json:"total_chat_insertion_events"`
TotalChatCopyEvents int `json:"total_chat_copy_events"`
}

// CopilotIDEChatEditor represents Copilot usage metrics for chatting with a model in the IDE, categorized by editor and model.
type CopilotIDEChatEditor struct {
Name string `json:"name"`
TotalEngagedUsers int `json:"total_engaged_users"`
Models []*CopilotIDEChatModel `json:"models"`
}

// CopilotIDEChat represents Copilot usage metrics for Copilot Chat in the IDE, categorized by editor and model.
type CopilotIDEChat struct {
TotalEngagedUsers int `json:"total_engaged_users"`
Editors []*CopilotIDEChatEditor `json:"editors"`
}

// CopilotDotcomChatModel represents Copilot usage metrics for chatting with a model in the webbrowser.
type CopilotDotcomChatModel struct {
Name string `json:"name"`
IsCustomModel bool `json:"is_custom_model"`
CustomModelTrainingDate *string `json:"custom_model_training_date,omitempty"`
TotalEngagedUsers int `json:"total_engaged_users"`
TotalChats int `json:"total_chats"`
}

// CopilotDotcomChat represents Copilot usage metrics for Copilot Chat in the webbrowser, categorized by model.
type CopilotDotcomChat struct {
TotalEngagedUsers int `json:"total_engaged_users"`
Models []*CopilotDotcomChatModel `json:"models"`
}

// CopilotDotcomPullRequestsModel represents Copilot usage metrics for pull requests in the webbrowser, categorized by model.
type CopilotDotcomPullRequestsModel struct {
Name string `json:"name"`
IsCustomModel bool `json:"is_custom_model"`
CustomModelTrainingDate *string `json:"custom_model_training_date,omitempty"`
TotalPRSummariesCreated int `json:"total_pr_summaries_created"`
TotalEngagedUsers int `json:"total_engaged_users"`
}

// CopilotDotcomPullRequestsRepository represents Copilot usage metrics for pull requests in the webbrowser, categorized by repository.
type CopilotDotcomPullRequestsRepository struct {
Name string `json:"name"`
TotalEngagedUsers int `json:"total_engaged_users"`
Models []*CopilotDotcomPullRequestsModel `json:"models"`
}

// CopilotDotcomPullRequests represents Copilot usage metrics for pull requests in the webbrowser, categorized by repository and model.
type CopilotDotcomPullRequests struct {
TotalEngagedUsers int `json:"total_engaged_users"`
Repositories []*CopilotDotcomPullRequestsRepository `json:"repositories"`
}

// CopilotMetrics represents Copilot usage metrics for a given day.
type CopilotMetrics struct {
Date string `json:"date"`
TotalActiveUsers *int `json:"total_active_users,omitempty"`
TotalEngagedUsers *int `json:"total_engaged_users,omitempty"`
CopilotIDECodeCompletions *CopilotIDECodeCompletions `json:"copilot_ide_code_completions,omitempty"`
CopilotIDEChat *CopilotIDEChat `json:"copilot_ide_chat,omitempty"`
CopilotDotcomChat *CopilotDotcomChat `json:"copilot_dotcom_chat,omitempty"`
CopilotDotcomPullRequests *CopilotDotcomPullRequests `json:"copilot_dotcom_pull_requests,omitempty"`
}

func (cp *CopilotSeatDetails) UnmarshalJSON(data []byte) error {
// Using an alias to avoid infinite recursion when calling json.Unmarshal
type alias CopilotSeatDetails
Expand Down Expand Up @@ -482,3 +601,107 @@ func (s *CopilotService) GetOrganizationTeamUsage(ctx context.Context, org, team

return usage, resp, nil
}

// GetEnterpriseMetrics gets Copilot usage metrics for an enterprise.
//
// GitHub API docs: https://docs.github.com/rest/copilot/copilot-metrics#get-copilot-metrics-for-an-enterprise
//
//meta:operation GET /enterprises/{enterprise}/copilot/metrics
func (s *CopilotService) GetEnterpriseMetrics(ctx context.Context, enterprise string, opts *CopilotMetricsListOptions) ([]*CopilotMetrics, *Response, error) {
u := fmt.Sprintf("enterprises/%v/copilot/metrics", enterprise)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}

req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}

var metrics []*CopilotMetrics
resp, err := s.client.Do(ctx, req, &metrics)
if err != nil {
return nil, resp, err
}

return metrics, resp, nil
}

// GetEnterpriseTeamMetrics gets Copilot usage metrics for an enterprise team.
//
// GitHub API docs: https://docs.github.com/rest/copilot/copilot-metrics#get-copilot-metrics-for-an-enterprise-team
//
//meta:operation GET /enterprises/{enterprise}/team/{team_slug}/copilot/metrics
func (s *CopilotService) GetEnterpriseTeamMetrics(ctx context.Context, enterprise, team string, opts *CopilotMetricsListOptions) ([]*CopilotMetrics, *Response, error) {
u := fmt.Sprintf("enterprises/%v/team/%v/copilot/metrics", enterprise, team)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}

req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}

var metrics []*CopilotMetrics
resp, err := s.client.Do(ctx, req, &metrics)
if err != nil {
return nil, resp, err
}

return metrics, resp, nil
}

// GetOrganizationMetrics gets Copilot usage metrics for an organization.
//
// GitHub API docs: https://docs.github.com/rest/copilot/copilot-metrics#get-copilot-metrics-for-an-organization
//
//meta:operation GET /orgs/{org}/copilot/metrics
func (s *CopilotService) GetOrganizationMetrics(ctx context.Context, org string, opts *CopilotMetricsListOptions) ([]*CopilotMetrics, *Response, error) {
u := fmt.Sprintf("orgs/%v/copilot/metrics", org)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}

req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}

var metrics []*CopilotMetrics
resp, err := s.client.Do(ctx, req, &metrics)
if err != nil {
return nil, resp, err
}

return metrics, resp, nil
}

// GetOrganizationTeamMetrics gets Copilot usage metrics for an organization team.
//
// GitHub API docs: https://docs.github.com/rest/copilot/copilot-metrics#get-copilot-metrics-for-a-team
//
//meta:operation GET /orgs/{org}/team/{team_slug}/copilot/metrics
func (s *CopilotService) GetOrganizationTeamMetrics(ctx context.Context, org, team string, opts *CopilotMetricsListOptions) ([]*CopilotMetrics, *Response, error) {
u := fmt.Sprintf("orgs/%v/team/%v/copilot/metrics", org, team)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}

req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}

var metrics []*CopilotMetrics
resp, err := s.client.Do(ctx, req, &metrics)
if err != nil {
return nil, resp, err
}

return metrics, resp, nil
}
Loading

0 comments on commit 717e93f

Please sign in to comment.