syntax = "proto3";

package exa.user_analytics_pb;

import "buf/validate/validate.proto";
import "exa/codeium_common_pb/codeium_common.proto";
import "google/protobuf/timestamp.proto";

enum QueryDataSource {
  QUERY_DATA_SOURCE_UNSPECIFIED = 0;
  QUERY_DATA_SOURCE_USER_DATA = 1;
  QUERY_DATA_SOURCE_CHAT_DATA = 2;
  QUERY_DATA_SOURCE_COMMAND_DATA = 3;
  QUERY_DATA_SOURCE_CASCADE_DATA = 4;
  QUERY_DATA_SOURCE_PCW_DATA = 5;
  QUERY_DATA_SOURCE_CASCADE_LINES_ANALYTICS = 6;
  QUERY_DATA_SOURCE_CASCADE_TOOL_ANALYTICS = 7;
}

enum QueryAggregation {
  QUERY_AGGREGATION_UNSPECIFIED = 0;
  QUERY_AGGREGATION_COUNT = 1;
  QUERY_AGGREGATION_SUM = 2;
  QUERY_AGGREGATION_AVG = 3;
  QUERY_AGGREGATION_MAX = 4;
  QUERY_AGGREGATION_MIN = 5;
}

enum QueryFilter {
  QUERY_FILTER_UNSPECIFIED = 0;
  QUERY_FILTER_EQUAL = 1;
  QUERY_FILTER_NOT_EQUAL = 2;
  QUERY_FILTER_GREATER_THAN = 3;
  QUERY_FILTER_LESS_THAN = 4;
  QUERY_FILTER_GE = 5;
  QUERY_FILTER_LE = 6;
}

enum IDEType {
  IDE_TYPE_UNSPECIFIED = 0;
  IDE_TYPE_WINDSURF = 1;
  IDE_TYPE_JETBRAINS = 2;
  IDE_TYPE_PLUGINS = 3;
  IDE_TYPE_CLI = 4;
}

message QuerySelectionField {
  .exa.user_analytics_pb.QueryAggregation aggregation_function = 1;
  string field = 2;
  string name = 3;
}

message QueryFilterField {
  .exa.user_analytics_pb.QueryFilter filter = 1;
  string name = 2;
  string value = 3;
}

message QueryAggregationField {
  string field = 1;
  string name = 2;
}

message QueryOrderField {
  bool ascending = 1;
  string name = 2;
}

message CustomQueryRequest {
  .exa.user_analytics_pb.QueryDataSource data_source = 1;
  repeated .exa.user_analytics_pb.QuerySelectionField selections = 2;
  repeated .exa.user_analytics_pb.QueryFilterField filters = 3;
  repeated .exa.user_analytics_pb.QueryAggregationField aggregations = 5;
  repeated .exa.user_analytics_pb.QueryOrderField orderings = 4;
  bool use_real_api_key = 6;
}

message QueryResponseItem {
  map<string, string> item = 1;
}

message CustomQueryResponse {
  repeated .exa.user_analytics_pb.QueryResponseItem response_items = 1;
}

message GetAnalyticsRequest {
  reserved 1;
  reserved 5;

  repeated .exa.user_analytics_pb.QueryRequest query_requests = 2;
  .google.protobuf.Timestamp start_timestamp = 3;
  .google.protobuf.Timestamp end_timestamp = 4;
  string group_id = 6;
  repeated string api_keys = 7;
  repeated string group_ids = 8;
  repeated .exa.user_analytics_pb.IDEType ide_types = 9;
}

message CascadeAnalyticsRequest {
  string service_key = 1;
  string group_name = 2;
  repeated string emails = 3;
  repeated string ide_types = 4;
  .google.protobuf.Timestamp start_timestamp = 5;
  .google.protobuf.Timestamp end_timestamp = 6;
  repeated .exa.user_analytics_pb.QueryRequest query_requests = 7;
  string multitenant_team_id = 8;
  string secret = 9;
  string team_id = 10;
}

message CascadeAnalyticsResponse {
  repeated .exa.user_analytics_pb.QueryResult query_results = 1;
}

message GetAnalyticsResponse {
  repeated .exa.user_analytics_pb.QueryResult query_results = 1;
}

message AnalyticsRequest {
  repeated .exa.user_analytics_pb.CustomQueryRequest query_requests = 1;
  string service_key = 2;
  string group_name = 3;
  .google.protobuf.Timestamp start_timestamp = 4;
  .google.protobuf.Timestamp end_timestamp = 5;
  string multitenant_team_id = 6;
  string secret = 7;
  string team_id = 8;
}

message AnalyticsResponse {
  repeated .exa.user_analytics_pb.CustomQueryResponse query_results = 1;
}

message UserPageAnalyticsRequest {
  string service_key = 1;
  string group_name = 2;
  .google.protobuf.Timestamp start_timestamp = 3;
  .google.protobuf.Timestamp end_timestamp = 4;
  string multitenant_team_id = 5;
  string secret = 6;
  string team_id = 7;
}

message UserPageAnalyticsResponse {
  repeated .exa.codeium_common_pb.UserTableStats user_table_stats = 1;
  .google.protobuf.Timestamp billing_cycle_start = 2;
  .google.protobuf.Timestamp billing_cycle_end = 3;
  string billing_mode = 4;
}

message QueryRequest {
  oneof request_type {
    .exa.user_analytics_pb.QueryRequestCompletionStats completion_stats = 1;
    .exa.user_analytics_pb.QueryRequestCompletionsByDay completions_by_day = 2;
    .exa.user_analytics_pb.QueryRequestCompletionsByLanguage completions_by_language = 3;
    .exa.user_analytics_pb.QueryRequestAllUsersCompletionStats all_users_completion_stats = 4;
    .exa.user_analytics_pb.QueryRequestAllUsersCompletionsByDay all_users_completions_by_day = 5;
    .exa.user_analytics_pb.QueryRequestAllUsersCompletionsByLanguage all_users_completions_by_language = 6;
    .exa.user_analytics_pb.QueryRequestCompletionsByIde completions_by_ide = 7;
    .exa.user_analytics_pb.QueryRequestCompletionsByIde all_users_completions_by_ide = 8;
    .exa.user_analytics_pb.QueryRequestCompletionsByApiKey completions_by_api_key = 9;
    .exa.user_analytics_pb.QueryRequestCompletionsByRepository completions_by_repository = 19;
    .exa.user_analytics_pb.QueryRequestChatsByDay chats_by_day = 10;
    .exa.user_analytics_pb.QueryRequestAllChatsByDay all_users_chats_by_day = 11;
    .exa.user_analytics_pb.QueryRequestChatStatsByModel chats_by_model = 12;
    .exa.user_analytics_pb.QueryRequestAllChatStatsByModel all_users_chats_by_model = 13;
    .exa.user_analytics_pb.QueryRequestActiveUserCount active_user_count = 14;
    .exa.user_analytics_pb.QueryRequestPercentCodeWritten percent_code_written = 15;
    .exa.user_analytics_pb.QueryRequestCharsPerOpportunity chars_per_opportunity = 16;
    .exa.user_analytics_pb.QueryRequestChatStats chat_stats = 17;
    .exa.user_analytics_pb.QueryRequestActiveDaysByApiKey active_days_by_api_key = 18;
    .exa.user_analytics_pb.QueryRequestCommandStats command_stats = 20;
    .exa.user_analytics_pb.CustomQueryRequest custom_query = 21;
    .exa.user_analytics_pb.UserPageAnalyticsRequest user_page_analytics = 22;
    .exa.user_analytics_pb.QueryRequestCascadeLines cascade_lines = 23;
    .exa.user_analytics_pb.QueryRequestCascadeToolUsage cascade_tool_usage = 24;
    .exa.user_analytics_pb.QueryRequestCascadeRuns cascade_runs = 25;
    .exa.user_analytics_pb.QueryRequestAllUsersCascadeLines all_users_cascade_lines = 26;
    .exa.user_analytics_pb.QueryRequestAllUsersCascadeToolUsage all_users_cascade_tool_usage = 27;
    .exa.user_analytics_pb.QueryRequestAllUsersCascadeRuns all_users_cascade_runs = 28;
    .exa.user_analytics_pb.QueryRequestAllUsersDailyActiveUserCounts all_users_daily_active_user_counts = 29;
    .exa.user_analytics_pb.QueryRequestAllUsersCommandStats all_users_command_stats = 30;
    .exa.user_analytics_pb.QueryRequestIndividualPercentCodeWritten individual_percent_code_written = 31;
    .exa.user_analytics_pb.QueryRequestCompletionsByLanguagePerUser completions_by_language_per_user = 32;
  }
}

message QueryResult {
  oneof result_type {
    .exa.user_analytics_pb.QueryResultCompletionStats completion_stats = 1;
    .exa.user_analytics_pb.QueryResultCompletionsByDay completions_by_day = 2;
    .exa.user_analytics_pb.QueryResultCompletionsByLanguage completions_by_language = 3;
    .exa.user_analytics_pb.QueryResultCompletionsByIde completions_by_ide = 4;
    .exa.user_analytics_pb.QueryResultCompletionsByApiKey completions_by_api_key = 5;
    .exa.user_analytics_pb.QueryResultCompletionsByRepository completions_by_repository = 13;
    .exa.user_analytics_pb.QueryResultChatsByDay chats_by_day = 6;
    .exa.user_analytics_pb.QueryResultChatStatsByModel chats_by_model = 7;
    .exa.user_analytics_pb.QueryResultActiveUserCount active_user_count = 8;
    .exa.user_analytics_pb.QueryResultPercentCodeWritten percent_code_written = 9;
    .exa.user_analytics_pb.QueryResultCharsPerOpportunity chars_per_opportunity = 10;
    .exa.user_analytics_pb.QueryResultChatStats chat_stats = 11;
    .exa.user_analytics_pb.QueryResultActiveDaysByApiKey active_days_by_api_key = 12;
    .exa.user_analytics_pb.QueryResultError error = 14;
    .exa.user_analytics_pb.QueryResultCommandStats command_stats = 15;
    .exa.user_analytics_pb.CustomQueryResponse custom_stats = 16;
    .exa.user_analytics_pb.UserPageAnalyticsResponse user_page_analytics = 17;
    .exa.user_analytics_pb.QueryResultCascadeLines cascade_lines = 18;
    .exa.user_analytics_pb.QueryResultCascadeToolUsage cascade_tool_usage = 19;
    .exa.user_analytics_pb.QueryResultCascadeRuns cascade_runs = 20;
    .exa.user_analytics_pb.QueryResultDailyActiveUserCounts daily_active_user_counts = 21;
    .exa.user_analytics_pb.QueryResultCompletionsByLanguagePerUser completions_by_language_per_user = 22;
  }
}

message DailyActiveUserCount {
  .google.protobuf.Timestamp day = 1;
  int64 active_user_count = 2;
}

message QueryResultDailyActiveUserCounts {
  repeated .exa.user_analytics_pb.DailyActiveUserCount daily_active_user_counts = 1;
}

message QueryRequestAllUsersDailyActiveUserCounts {
}

message QueryRequestCompletionStats {
}

message QueryResultCompletionStats {
  .exa.codeium_common_pb.CompletionStatistics completion_statistics = 1;
}

message QueryRequestCompletionsByDay {
  string time_zone = 1;
}

message QueryResultCompletionsByDay {
  repeated .exa.codeium_common_pb.CompletionByDateEntry completions_by_day = 1;
}

message QueryRequestCompletionsByLanguage {
}

message QueryResultCompletionsByLanguage {
  repeated .exa.codeium_common_pb.CompletionByLanguageEntry completions_by_language = 1;
}

message QueryRequestCompletionsByLanguagePerUser {
}

message CompletionsByLanguagePerUserEntry {
  string api_key = 1;
  repeated .exa.codeium_common_pb.CompletionByLanguageEntry completions_by_language = 2;
}

message QueryResultCompletionsByLanguagePerUser {
  repeated .exa.user_analytics_pb.CompletionsByLanguagePerUserEntry entries = 1;
}

message QueryRequestCompletionsByIde {
}

message QueryResultCompletionsByIde {
  map<string, .exa.codeium_common_pb.CompletionStatistics> completions_by_ide = 1;
}

message QueryRequestCompletionsByRepository {
}

message QueryResultCompletionsByRepository {
  map<string, .exa.codeium_common_pb.CompletionStatistics> completions_by_repository = 1;
}

message QueryRequestChatsByDay {
  string time_zone = 1;
}

message QueryResultChatsByDay {
  repeated .exa.codeium_common_pb.ChatStatsByDateEntry chats_by_day = 1;
}

message QueryRequestAllChatsByDay {
  string time_zone = 1;
}

message QueryRequestActiveUserCount {
  string time_zone = 1;
  .google.protobuf.Timestamp start_timestamp = 2;
  .google.protobuf.Timestamp end_timestamp = 3;
}

message QueryRequestActiveUserCountByUsers {
  string time_zone = 1;
}

message QueryRequestDailyActiveUserCounts {
}

message QueryRequestChatStatsByModel {
}

message QueryRequestAllChatStatsByModel {
}

message QueryResultChatStatsByModel {
  repeated .exa.codeium_common_pb.ChatStatsByModelEntry chats_by_model = 1;
}

message QueryRequestAllUsersCompletionsByDay {
  string time_zone = 1;
}

message QueryRequestAllUsersCompletionsByLanguage {
}

message QueryRequestAllUsersCompletionStats {
}

message QueryRequestCompletionsByApiKey {
}

message QueryResultCompletionsByApiKey {
  map<string, .exa.codeium_common_pb.CompletionStatistics> completions_by_api_key = 1;
}

message QueryResultActiveUserCount {
  int64 active_user_count = 1;
}

message QueryRequestIndividualPercentCodeWritten {
}

message QueryRequestPercentCodeWritten {
}

message QueryResultPercentCodeWritten {
  double percent_code_written = 1;
  int64 codeium_bytes_by_autocomplete = 2;
  int64 codeium_bytes_by_command = 3;
  int64 codeium_bytes_by_supercomplete = 7;
  int64 codeium_bytes_by_cascade = 8;
  int64 user_bytes = 4;
  int64 codeium_bytes = 5;
  int64 total_bytes = 6;
}

message QueryRequestCharsPerOpportunity {
}

message QueryResultCharsPerOpportunity {
  double chars_per_opportunity = 1;
  uint64 num_bytes_accepted = 2;
  uint64 num_completion_attempts = 3;
}

message QueryRequestChatStats {
}

message QueryResultChatStats {
  .exa.codeium_common_pb.ChatStats chat_stats = 1;
}

message QueryRequestCommandStats {
}

message QueryRequestAllUsersCommandStats {
}

message QueryResultCommandStats {
  .exa.codeium_common_pb.CommandStats command_stats = 1;
}

message QueryRequestActiveDaysByApiKey {
}

message QueryResultActiveDaysByApiKey {
  map<string, uint32> active_days_by_api_key = 1;
}

message QueryResultError {
  string error = 1;
}

message QueryRequestCascadeLines {
}

message CascadeLineQueryEntry {
  .google.protobuf.Timestamp day = 1;
  int64 lines_suggested = 2;
  int64 lines_accepted = 3;
}

message QueryResultCascadeLines {
  repeated .exa.user_analytics_pb.CascadeLineQueryEntry cascade_lines = 1;
}

message QueryRequestCascadeToolUsage {
}

message CascadeToolUsageQueryEntry {
  .google.protobuf.Timestamp day = 1;
  string tool = 2;
  int64 count = 3;
}

message QueryResultCascadeToolUsage {
  repeated .exa.user_analytics_pb.CascadeToolUsageQueryEntry cascade_tool_usage = 1;
}

message QueryRequestCascadeRuns {
}

message CascadeRunsQueryEntry {
  .google.protobuf.Timestamp day = 1;
  string model = 2;
  string mode = 3;
  int64 messages_sent = 4;
  int64 prompts_used = 5;
  string cascade_id = 6;
}

message QueryResultCascadeRuns {
  repeated .exa.user_analytics_pb.CascadeRunsQueryEntry cascade_runs = 1;
}

message QueryRequestAllUsersCascadeRuns {
}

message QueryRequestAllUsersCascadeToolUsage {
}

message QueryRequestAllUsersCascadeLines {
}

message GetGlobalLeaderboardApiKeyRequest {
}

message GetGlobalLeaderboardApiKeyResponse {
  string api_key = 1;
}

message GetBigQueryAnalyticsRequest {
  string api_key = 1;
  .google.protobuf.Timestamp start_timestamp = 2;
  .google.protobuf.Timestamp end_timestamp = 3;
  repeated .exa.user_analytics_pb.BigQueryRequest query_requests = 4;
}

message GetBigQueryAnalyticsResponse {
  repeated .exa.user_analytics_pb.BigQueryResult query_results = 1;
}

message BigQueryRequest {
  oneof request_type {
    .exa.user_analytics_pb.BigQueryLeaderboardRequest leaderboard_request = 1;
  }
}

message BigQueryResult {
  oneof result_type {
    .exa.user_analytics_pb.BigQueryResultError error = 1;
    .exa.user_analytics_pb.BigQueryLeaderboardResult leaderboard_result = 2;
  }
}

message BigQueryResultError {
  string error = 1;
}

message BigQueryLeaderboardRequest {
}

message BigQueryLeaderboardResult {
  repeated .exa.user_analytics_pb.ModelStats model_stats = 1;
  .google.protobuf.Timestamp last_queried_at = 2;
}

message ModelStats {
  reserved 5;
  reserved "model_provider";

  string model = 1;
  int64 elo_rating = 2;
  int64 votes = 3;
  double win_rate = 4;
  int64 confidence_lower = 6;
  int64 confidence_upper = 7;
  double model_speed = 8;
  string model_group = 9;
}

message GetDevinUserAnalyticsRequest {
  string start_date = 1 [deprecated = true];
  string end_date = 2 [deprecated = true];
  .google.protobuf.Timestamp start_date_ts = 3;
  .google.protobuf.Timestamp end_date_ts = 4;
}

message GetDevinUserAnalyticsResponse {
  repeated .exa.user_analytics_pb.DevinUsageEntry devin_usage_entries = 1;
  double total_acus = 2;
}

message DevinUsageEntry {
  string day = 1;
  double acus = 2;
}

service UserAnalyticsService {
  rpc Analytics (.exa.user_analytics_pb.AnalyticsRequest) returns (.exa.user_analytics_pb.AnalyticsResponse);
  rpc UserPageAnalytics (.exa.user_analytics_pb.UserPageAnalyticsRequest) returns (.exa.user_analytics_pb.UserPageAnalyticsResponse);
  rpc CascadeAnalytics (.exa.user_analytics_pb.CascadeAnalyticsRequest) returns (.exa.user_analytics_pb.CascadeAnalyticsResponse);
  rpc GetAnalytics (.exa.user_analytics_pb.GetAnalyticsRequest) returns (.exa.user_analytics_pb.GetAnalyticsResponse);
  rpc GetGlobalLeaderboardApiKey (.exa.user_analytics_pb.GetGlobalLeaderboardApiKeyRequest) returns (.exa.user_analytics_pb.GetGlobalLeaderboardApiKeyResponse);
  rpc GetBigQueryAnalytics (.exa.user_analytics_pb.GetBigQueryAnalyticsRequest) returns (.exa.user_analytics_pb.GetBigQueryAnalyticsResponse);
  rpc GetDevinUserAnalytics (.exa.user_analytics_pb.GetDevinUserAnalyticsRequest) returns (.exa.user_analytics_pb.GetDevinUserAnalyticsResponse);
}
