diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 367d343..df1c574 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -56,7 +56,7 @@ jobs: -e SESSION_SECRET=dummy \ api:test "@org" - uses: actions/upload-artifact@v4 - if: ${{ !cancelled() }} + if: always() with: name: playwright-report-docker-org path: test-results-docker-org/ @@ -89,7 +89,7 @@ jobs: -e SESSION_SECRET=dummy \ api:test "@ent" - uses: actions/upload-artifact@v4 - if: ${{ !cancelled() }} + if: always() with: name: playwright-report-docker-ent path: test-results-docker-ent/ diff --git a/README.md b/README.md index 4e3c9c1..a127e07 100644 --- a/README.md +++ b/README.md @@ -11,49 +11,51 @@ This application displays a set of charts with various metrics related to GitHub https://github.com/github-copilot-resources/copilot-metrics-viewer/assets/3329307/bc7e2a16-cc73-43c4-887a-b50809c08533 - ## Charts ## Key Metrics +>[!NOTE] +> Metrics details are described in detail in [GitHub API response schema](https://docs.github.com/en/rest/copilot/copilot-metrics?apiVersion=2022-11-28#get-copilot-metrics-for-an-organization) + Here are the key metrics visualized in these charts: -1. **Acceptance Rate:** This metric represents the ratio of accepted lines to the total lines suggested by GitHub Copilot. This rate is an indicator of the relevance and usefulness of Copilot's suggestions.

- image + image

-2. **Total Suggestions** This chart illustrates the total number of code suggestions made by GitHub Copilot. It offers a view of the tool's activity and its engagement with users over time. +1. **Acceptance Rate:** This metric represents the ratio of accepted lines and suggestions to the total suggested by GitHub Copilot. This rate is an indicator of the relevance and usefulness of Copilot's suggestions. However, as with any metric, it should be used with caution as developers use Copilot in many different ways (research, confirm, verify, etc., not always "inject"). +

+ image +

-3. **Total Acceptances:** This visualization focuses on the total number of suggestions accepted by users. +2. **Total Suggestions:** This chart illustrates the total number of code suggestions made by GitHub Copilot. It offers a view of the tool's activity and its engagement with users over time. +3. **Total Acceptances:** This visualization focuses on the total number of suggestions accepted by users.

- image + image

4. **Total Lines Suggested:** Showcases the total number of lines of code suggested by GitHub Copilot. This gives an idea of the volume of code generation and assistance provided. -5. **Total Lines Accepted:** As the name says, the total lines of code accepted by users (full acceptances) offering insights into how much of the suggested code is actually being utilized incorporated to the codebase. - +5. **Total Lines Accepted:** As the name suggests, the total lines of code accepted by users (full acceptances) offering insights into how much of the suggested code is actually being utilized and incorporated into the codebase.

- image + image

6. **Total Active Users:** Represents the number of active users engaging with GitHub Copilot. This helps in understanding the user base growth and adoption rate. -

- image + image

## Languages Breakdown Analysis -Pie charts with the top 5 languages by accepted prompts and acceptance rate are displayed at the top. +Pie charts with the top 5 languages by accepted prompts and acceptance rate (by count/by lines) are displayed at the top.

- image + image

The language breakdown analysis tab also displays a table showing the Accepted Prompts, Accepted Lines of Code, and Acceptance Rate (%) for each language over the past 28 days. The entries are sorted by the number of _accepted lines of code descending_. -

- image + image

## Copilot Chat Metrics @@ -66,25 +68,24 @@ The language breakdown analysis tab also displays a table showing the Accepted P 2. **Cumulative Number of Acceptances:** This metric shows the total number of lines of code suggested by Copilot that have been accepted by users over the past 28 days. -3. **Total Turns | Total Acceptances Count:** This is a chart that displays the total number of turns and acceptances +3. **Total Turns | Total Acceptances Count:** This is a chart that displays the total number of turns and acceptances. -4. **Total Active Copilot Chat Users:** a bar chart that illustrates the total number of users who have actively interacted with Copilot over the past 28 days. +4. **Total Active Copilot Chat Users:** A bar chart that illustrates the total number of users who have actively interacted with Copilot over the past 28 days. ## Seat Analysis

image

-1. **Total Assigned:** This metric represents the total number of Copilot seats assigned within current organization/enterprise. +1. **Total Assigned:** This metric represents the total number of Copilot seats assigned within the current organization/enterprise. 2. **Assigned But Never Used:** This metric shows seats that were assigned but never used within the current organization/enterprise. The assigned timestamp is also displayed in the chart. -3. **No Activity in the Last 7 days:** never used seats or seats used, but with no activity in the past 7 days. +3. **No Activity in the Last 7 Days:** Never used seats or seats used, but with no activity in the past 7 days. -4. **No Activity in the last 7 days (including never used seats):** a table to display seats that have had no activity in the past 7 days, ordered by the date of last activity. Seats that were used earlier are displayed at the top. +4. **No Activity in the Last 7 Days (including never used seats):** A table to display seats that have had no activity in the past 7 days, ordered by the date of last activity. Seats that were used earlier are displayed at the top. - -## Setup instructions +## Setup Instructions In the `.env` file, you can configure several environment variables that control the behavior of the application. @@ -100,10 +101,11 @@ For example, if you want to target the API calls to an organization, you would s ```` VUE_APP_SCOPE=organization -VUE_APP_GITHUB_ORG= +VUE_APP_GITHUB_ORG= VUE_APP_GITHUB_ENT= ```` + #### VUE_APP_GITHUB_TEAM The `VUE_APP_GITHUB_TEAM` environment variable filters metrics for a specific GitHub team within an Enterprise or Organization account. @@ -111,66 +113,69 @@ The `VUE_APP_GITHUB_TEAM` environment variable filters metrics for a specific Gi ```` VUE_APP_GITHUB_TEAM= - ```` #### VUE_APP_MOCKED_DATA To access Copilot metrics from the last 28 days via the API and display actual data, set the following boolean environment variable to `false`: -``` - VUE_APP_MOCKED_DATA=false -``` +```` +VUE_APP_MOCKED_DATA=false +```` #### VUE_APP_GITHUB_TOKEN + Specifies the GitHub Personal Access Token utilized for API requests. Generate this token with the following scopes: _copilot_, _manage_billing:copilot_, _manage_billing:enterprise_, _read:enterprise_, _read:org_. -``` - VUE_APP_GITHUB_TOKEN= -``` +```` +VUE_APP_GITHUB_TOKEN= +```` -## Install dependencies -``` +## Install Dependencies + +```bash npm install ``` -### Compiles and runs the application -``` +### Compiles and Runs the Application + +```bash npm run serve ``` -### Docker build -``` +### Docker Build + +```bash docker build -t copilot-metrics-viewer . ``` -### Docker run -``` +### Docker Run + +```bash docker run -p 8080:80 --env-file ./.env copilot-metrics-viewer ``` + The application will be accessible at http://localhost:8080 ## Running with API Proxy -Project can run with an API proxy which hides GitHub tokens and is secure enough to be deployed. -Api Proxy project is in `\api` directory. Vue app makes the calls to `/api/github` which then are proxied to `https://api.github.com` with appropriate bearer token. - -Proxy can authenticate user using GitHub App. In order to do that, following environment variables are required: +The project can run with an API proxy which hides GitHub tokens and is secure enough to be deployed. +The API Proxy project is in the `\api` directory. The Vue app makes the calls to `/api/github` which are then proxied to `https://api.github.com` with the appropriate bearer token. -* `GITHUB_CLIENT_ID` - client Id of the GitHub App registered and installed in the enterprise/org with permissions listed above. -* `GITHUB_CLIENT_SECRET` - client secret of the GitHub App -* `SESSION_SECRET` - random string for securing session state +The proxy can authenticate the user using a GitHub App. In order to do that, the following environment variables are required: -If you want use a custom path for your `.env` file you can set the environment variable `DOTENV_CONFIG_PATH`. +* `GITHUB_CLIENT_ID` - client ID of the GitHub App registered and installed in the enterprise/org with permissions listed above. +* `GITHUB_CLIENT_SECRET` - client secret of the GitHub App. +* `SESSION_SECRET` - random string for securing session state. -https://github.com/user-attachments/assets/e5596067-da9c-409d-9b9f-0a688cc1f2c4 +If you want to use a custom path for your `.env` file, you can set the environment variable `DOTENV_CONFIG_PATH`. -It's also possible to run with **PAT Token**, see examples below for required variables. +It's also possible to run with a **PAT Token**, see examples below for required variables. -For local development register `http://localhost:3000/callback` as GH App callback Uri. -For deployed version use the Uri of your app. +For local development, register `http://localhost:3000/callback` as the GitHub App callback URI. +For the deployed version, use the URI of your app. -To build and run the app with API proxy: +To build and run the app with the API proxy: ```bash docker build -t copilot-metrics-viewer-with-proxy -f api.Dockerfile . @@ -182,7 +187,7 @@ To run: docker run -it --rm -p 8080:3000 --env-file ./.env copilot-metrics-viewer-with-proxy ``` -Or with custom path for your `.env` file: +Or with a custom path for your `.env` file: ```bash docker run -it --rm -p 8080:3000 \ @@ -191,7 +196,7 @@ docker run -it --rm -p 8080:3000 \ copilot-metrics-viewer-with-proxy ``` -Proxy can also run with token hardcoded on the backend (which hides it from frontend calls), here's a sample: +The proxy can also run with the token hardcoded on the backend (which hides it from frontend calls), here's a sample: ```bash docker run -it --rm -p 3000:3000 \ @@ -225,6 +230,6 @@ This project is licensed under the terms of the MIT open source license. Please ## Support -This project is independently developed and maintained, and is not an official GitHub product. It thrives through the dedicated efforts of ([@martedesco](https://github.com/martedesco)), ([@karpikpl](https://github.com/karpikpl)) our wonderful contributors. A heartfelt thanks to all our contributors! ✨ +This project is independently developed and maintained, and is not an official GitHub product. It thrives through the dedicated efforts of ([@martedesco](https://github.com/martedesco)), ([@karpikpl](https://github.com/karpikpl)) and our wonderful contributors. A heartfelt thanks to all our contributors! ✨ I aim to provide support through [GitHub Issues](https://github.com/github-copilot-resources/copilot-metrics-viewer/issues). While I strive to stay responsive, I can't guarantee immediate responses. For critical issues, please include "CRITICAL" in the title for quicker attention. 🙏🏼 diff --git a/api/server.mjs b/api/server.mjs index 195d89a..e51b205 100644 --- a/api/server.mjs +++ b/api/server.mjs @@ -17,6 +17,10 @@ const MemoryStore = MemoryStoreFactory(session); const limiter = RateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100, // max 100 requests per windowMs + skip: (req) => { + // Skip rate limiting for localhost + return isLocalhost(req); + } }); if (DOTENV_CONFIG_PATH) { @@ -27,8 +31,13 @@ if (DOTENV_CONFIG_PATH) { } const app = express(); +console.log('ENVIRONMENT: ', app.get('env')); + +// Disable rate limiter and secure cookies for localhost +const isLocalhost = (req) => { + return req.hostname === 'localhost' || req.hostname === '127.0.0.1'; +}; -// apply rate limiter to all requests app.use(limiter); app.use(session({ @@ -38,7 +47,8 @@ app.use(session({ store: new MemoryStore({ checkPeriod: 86400000 // prune expired entries every 24h }), - cookie: { secure: process.env.IS_PROD ? true : false, maxAge: 86400000 } + // may need to use secure: false if using http during local development + cookie: { secure: app.get('env') === 'production', maxAge: 86400000 } })); // Middleware to add Authorization header @@ -70,16 +80,24 @@ const mockResponses = (proxyServer, options) => { // Do not send to GitHub when mocked switch (req.path) { case "/orgs/octodemo/copilot/usage": - res.json(JSON.parse(readFileSync(path.join(__dirname, '../mock-data/organization_response_sample.json'), 'utf8'))); + case "/orgs/octodemo/team/the-a-team/copilot/usage": + res.json(JSON.parse(readFileSync(path.join(__dirname, '../mock-data/organization_usage_response_sample.json'), 'utf8'))); + break; + case "/orgs/octodemo/copilot/metrics": + case "/orgs/octodemo/team/the-a-team/copilot/metrics": + res.json(JSON.parse(readFileSync(path.join(__dirname, '../mock-data/organization_metrics_response_sample.json'), 'utf8'))); break; case "/orgs/octodemo/copilot/billing/seats": - res.json(JSON.parse(readFileSync(path.join(__dirname, '../mock-data/organization_response_sample_seats.json'), 'utf8'))); + res.json(JSON.parse(readFileSync(path.join(__dirname, '../mock-data/organization_seats_response_sample.json'), 'utf8'))); break; case "/enterprises/octodemo/copilot/usage": - res.json(JSON.parse(readFileSync(path.join(__dirname, '../mock-data/enterprise_response_sample.json'), 'utf8'))); + res.json(JSON.parse(readFileSync(path.join(__dirname, '../mock-data/enterprise_usage_response_sample.json'), 'utf8'))); + break; + case "/enterprises/octodemo/copilot/metrics": + res.json(JSON.parse(readFileSync(path.join(__dirname, '../mock-data/enterprise_metrics_response_sample.json'), 'utf8'))); break; case "/enterprises/octodemo/copilot/billing/seats": - res.json(JSON.parse(readFileSync(path.join(__dirname, '../mock-data/enterprise_response_sample_seats.json'), 'utf8'))); + res.json(JSON.parse(readFileSync(path.join(__dirname, '../mock-data/enterprise_seats_response_sample.json'), 'utf8'))); break; default: res.status(418).send('🫖Request Not Mocked'); diff --git a/images/Acceptance_rate_by_lines.png b/images/Acceptance_rate_by_lines.png new file mode 100644 index 0000000..5e85dba Binary files /dev/null and b/images/Acceptance_rate_by_lines.png differ diff --git a/images/Acceptance_rate_bycount.png b/images/Acceptance_rate_bycount.png new file mode 100644 index 0000000..0451879 Binary files /dev/null and b/images/Acceptance_rate_bycount.png differ diff --git a/images/KeyMetrics.png b/images/KeyMetrics.png new file mode 100644 index 0000000..56c0c46 Binary files /dev/null and b/images/KeyMetrics.png differ diff --git a/images/Language_breakdown.png b/images/Language_breakdown.png new file mode 100644 index 0000000..3181ea1 Binary files /dev/null and b/images/Language_breakdown.png differ diff --git a/images/Language_breakdown_list.png b/images/Language_breakdown_list.png new file mode 100644 index 0000000..06baeca Binary files /dev/null and b/images/Language_breakdown_list.png differ diff --git a/images/MainMetrics.png b/images/MainMetrics.png new file mode 100644 index 0000000..cb673b9 Binary files /dev/null and b/images/MainMetrics.png differ diff --git a/images/Total Lines.png b/images/Total Lines.png new file mode 100644 index 0000000..83f2d30 Binary files /dev/null and b/images/Total Lines.png differ diff --git a/images/Total_Active_users.png b/images/Total_Active_users.png new file mode 100644 index 0000000..491f4d7 Binary files /dev/null and b/images/Total_Active_users.png differ diff --git a/images/Total_suggestions_count.png b/images/Total_suggestions_count.png new file mode 100644 index 0000000..f09fac3 Binary files /dev/null and b/images/Total_suggestions_count.png differ diff --git a/mock-data/enterprise_metrics_response_sample.json b/mock-data/enterprise_metrics_response_sample.json new file mode 100644 index 0000000..0d9adb8 --- /dev/null +++ b/mock-data/enterprise_metrics_response_sample.json @@ -0,0 +1,2504 @@ +[ + { + "date": "2024-11-04", + "copilot_ide_chat": { + "editors": [ + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 34, + "is_custom_model": false, + "total_engaged_users": 2, + "total_chat_copy_events": 1, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 2 + }, + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 10, + "is_custom_model": false, + "total_engaged_users": 2, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 1 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 4 + }, + "total_active_users": 4, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 4, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "kotlin", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 3, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 11 + }, + { + "name": "json", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 37 + }, + { + "name": "python", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 2, + "total_code_lines_accepted": 12, + "total_code_lines_suggested": 13 + } + ], + "is_custom_model": false, + "total_engaged_users": 2 + } + ], + "total_engaged_users": 2 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "python", + "total_engaged_users": 2, + "total_code_acceptances": 9, + "total_code_suggestions": 15, + "total_code_lines_accepted": 8, + "total_code_lines_suggested": 21 + } + ], + "is_custom_model": false, + "total_engaged_users": 2 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 3 + } + }, + { + "date": "2024-11-05", + "copilot_ide_chat": { + "editors": [ + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 12, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + }, + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 18, + "is_custom_model": false, + "total_engaged_users": 2, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 3 + }, + "total_active_users": 3, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 3, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "kotlin", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "go", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 3, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 3 + } + ], + "is_custom_model": false, + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + } + }, + { + "date": "2024-11-06", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 231, + "is_custom_model": false, + "total_engaged_users": 17, + "total_chat_copy_events": 69, + "total_chat_insertion_events": 23 + } + ], + "total_engaged_users": 17 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 30, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 18 + }, + "total_active_users": 29, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 29, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 20, + "total_code_acceptances": 345, + "total_code_suggestions": 1357, + "total_code_lines_accepted": 613, + "total_code_lines_suggested": 4843 + }, + { + "name": "groovy", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "go", + "total_engaged_users": 5, + "total_code_acceptances": 148, + "total_code_suggestions": 838, + "total_code_lines_accepted": 226, + "total_code_lines_suggested": 1860 + }, + { + "name": "xml", + "total_engaged_users": 4, + "total_code_acceptances": 10, + "total_code_suggestions": 34, + "total_code_lines_accepted": 11, + "total_code_lines_suggested": 98 + }, + { + "name": "json", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 3, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 3 + }, + { + "name": "sql", + "total_engaged_users": 2, + "total_code_acceptances": 4, + "total_code_suggestions": 71, + "total_code_lines_accepted": 4, + "total_code_lines_suggested": 149 + }, + { + "name": "yaml", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "unknown", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 3, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 5 + } + ], + "is_custom_model": false, + "total_engaged_users": 24 + } + ], + "total_engaged_users": 24 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "python", + "total_engaged_users": 2, + "total_code_acceptances": 16, + "total_code_suggestions": 41, + "total_code_lines_accepted": 14, + "total_code_lines_suggested": 59 + } + ], + "is_custom_model": false, + "total_engaged_users": 2 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 25 + } + }, + { + "date": "2024-11-07", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 245, + "is_custom_model": false, + "total_engaged_users": 16, + "total_chat_copy_events": 64, + "total_chat_insertion_events": 40 + } + ], + "total_engaged_users": 16 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 18, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 16 + }, + "total_active_users": 27, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 27, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 18, + "total_code_acceptances": 356, + "total_code_suggestions": 1204, + "total_code_lines_accepted": 599, + "total_code_lines_suggested": 3270 + }, + { + "name": "xml", + "total_engaged_users": 3, + "total_code_acceptances": 3, + "total_code_suggestions": 15, + "total_code_lines_accepted": 6, + "total_code_lines_suggested": 45 + }, + { + "name": "sql", + "total_engaged_users": 2, + "total_code_acceptances": 3, + "total_code_suggestions": 12, + "total_code_lines_accepted": 3, + "total_code_lines_suggested": 33 + }, + { + "name": "go", + "total_engaged_users": 5, + "total_code_acceptances": 305, + "total_code_suggestions": 1185, + "total_code_lines_accepted": 495, + "total_code_lines_suggested": 2773 + }, + { + "name": "unknown", + "total_engaged_users": 3, + "total_code_acceptances": 5, + "total_code_suggestions": 68, + "total_code_lines_accepted": 14, + "total_code_lines_suggested": 147 + }, + { + "name": "yaml", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 3, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 3 + }, + { + "name": "shellscript", + "total_engaged_users": 2, + "total_code_acceptances": 1, + "total_code_suggestions": 1, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 2 + }, + { + "name": "groovy", + "total_engaged_users": 2, + "total_code_acceptances": 3, + "total_code_suggestions": 12, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 28 + } + ], + "is_custom_model": false, + "total_engaged_users": 23 + } + ], + "total_engaged_users": 23 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "cpp", + "total_engaged_users": 2, + "total_code_acceptances": 9, + "total_code_suggestions": 13, + "total_code_lines_accepted": 9, + "total_code_lines_suggested": 13 + }, + { + "name": "typescript", + "total_engaged_users": 2, + "total_code_acceptances": 6, + "total_code_suggestions": 12, + "total_code_lines_accepted": 5, + "total_code_lines_suggested": 13 + } + ], + "is_custom_model": false, + "total_engaged_users": 2 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 24 + } + }, + { + "date": "2024-11-08", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 86, + "is_custom_model": false, + "total_engaged_users": 11, + "total_chat_copy_events": 15, + "total_chat_insertion_events": 9 + } + ], + "total_engaged_users": 11 + } + ], + "total_engaged_users": 11 + }, + "total_active_users": 21, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 21, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "go", + "total_engaged_users": 5, + "total_code_acceptances": 207, + "total_code_suggestions": 860, + "total_code_lines_accepted": 312, + "total_code_lines_suggested": 2589 + }, + { + "name": "unknown", + "total_engaged_users": 4, + "total_code_acceptances": 17, + "total_code_suggestions": 91, + "total_code_lines_accepted": 28, + "total_code_lines_suggested": 472 + }, + { + "name": "java", + "total_engaged_users": 14, + "total_code_acceptances": 158, + "total_code_suggestions": 604, + "total_code_lines_accepted": 269, + "total_code_lines_suggested": 1874 + }, + { + "name": "xml", + "total_engaged_users": 3, + "total_code_acceptances": 9, + "total_code_suggestions": 33, + "total_code_lines_accepted": 13, + "total_code_lines_suggested": 129 + }, + { + "name": "sql", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "groovy", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 5, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 19 + } + ], + "is_custom_model": false, + "total_engaged_users": 19 + } + ], + "total_engaged_users": 19 + } + ], + "total_engaged_users": 19 + } + }, + { + "date": "2024-11-09", + "copilot_ide_chat": { + "editors": [ + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 128, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 9, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + }, + "total_active_users": 1, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 1, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "rust", + "total_engaged_users": 2, + "total_code_acceptances": 38, + "total_code_suggestions": 175, + "total_code_lines_accepted": 43, + "total_code_lines_suggested": 529 + }, + { + "name": "unknown", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + } + ], + "is_custom_model": false, + "total_engaged_users": 2 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 2 + } + }, + { + "date": "2024-11-10", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 6, + "is_custom_model": false, + "total_engaged_users": 2, + "total_chat_copy_events": 2, + "total_chat_insertion_events": 1 + } + ], + "total_engaged_users": 2 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 3, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 2 + }, + "total_active_users": 5, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 5, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "go", + "total_engaged_users": 2, + "total_code_acceptances": 26, + "total_code_suggestions": 94, + "total_code_lines_accepted": 27, + "total_code_lines_suggested": 192 + }, + { + "name": "java", + "total_engaged_users": 3, + "total_code_acceptances": 8, + "total_code_suggestions": 55, + "total_code_lines_accepted": 9, + "total_code_lines_suggested": 252 + } + ], + "is_custom_model": false, + "total_engaged_users": 4 + } + ], + "total_engaged_users": 4 + } + ], + "total_engaged_users": 4 + } + }, + { + "date": "2024-11-11", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 90, + "is_custom_model": false, + "total_engaged_users": 11, + "total_chat_copy_events": 34, + "total_chat_insertion_events": 24 + } + ], + "total_engaged_users": 11 + } + ], + "total_engaged_users": 11 + }, + "total_active_users": 23, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 23, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 15, + "total_code_acceptances": 241, + "total_code_suggestions": 1073, + "total_code_lines_accepted": 396, + "total_code_lines_suggested": 3252 + }, + { + "name": "xml", + "total_engaged_users": 4, + "total_code_acceptances": 6, + "total_code_suggestions": 22, + "total_code_lines_accepted": 7, + "total_code_lines_suggested": 70 + }, + { + "name": "go", + "total_engaged_users": 5, + "total_code_acceptances": 160, + "total_code_suggestions": 1086, + "total_code_lines_accepted": 177, + "total_code_lines_suggested": 2498 + }, + { + "name": "unknown", + "total_engaged_users": 3, + "total_code_acceptances": 6, + "total_code_suggestions": 58, + "total_code_lines_accepted": 6, + "total_code_lines_suggested": 99 + }, + { + "name": "yaml", + "total_engaged_users": 2, + "total_code_acceptances": 1, + "total_code_suggestions": 7, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 18 + }, + { + "name": "groovy", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 3, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 20 + } + ], + "is_custom_model": false, + "total_engaged_users": 20 + } + ], + "total_engaged_users": 20 + } + ], + "total_engaged_users": 20 + } + }, + { + "date": "2024-11-12", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 78, + "is_custom_model": false, + "total_engaged_users": 9, + "total_chat_copy_events": 24, + "total_chat_insertion_events": 14 + } + ], + "total_engaged_users": 9 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 57, + "is_custom_model": false, + "total_engaged_users": 2, + "total_chat_copy_events": 1, + "total_chat_insertion_events": 2 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 11 + }, + "total_active_users": 26, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 26, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 18, + "total_code_acceptances": 275, + "total_code_suggestions": 1059, + "total_code_lines_accepted": 444, + "total_code_lines_suggested": 3152 + }, + { + "name": "go", + "total_engaged_users": 5, + "total_code_acceptances": 142, + "total_code_suggestions": 725, + "total_code_lines_accepted": 183, + "total_code_lines_suggested": 1687 + }, + { + "name": "xml", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 11, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 18 + }, + { + "name": "yaml", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 13, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 33 + }, + { + "name": "unknown", + "total_engaged_users": 4, + "total_code_acceptances": 3, + "total_code_suggestions": 31, + "total_code_lines_accepted": 3, + "total_code_lines_suggested": 79 + } + ], + "is_custom_model": false, + "total_engaged_users": 23 + } + ], + "total_engaged_users": 23 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "typescript", + "total_engaged_users": 2, + "total_code_acceptances": 10, + "total_code_suggestions": 22, + "total_code_lines_accepted": 12, + "total_code_lines_suggested": 29 + }, + { + "name": "json", + "total_engaged_users": 2, + "total_code_acceptances": 1, + "total_code_suggestions": 1, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 1 + }, + { + "name": "unknown", + "total_engaged_users": 2, + "total_code_acceptances": 1, + "total_code_suggestions": 7, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 9 + }, + { + "name": "python", + "total_engaged_users": 2, + "total_code_acceptances": 28, + "total_code_suggestions": 81, + "total_code_lines_accepted": 33, + "total_code_lines_suggested": 101 + } + ], + "is_custom_model": false, + "total_engaged_users": 3 + } + ], + "total_engaged_users": 3 + } + ], + "total_engaged_users": 24 + } + }, + { + "date": "2024-11-13", + "copilot_ide_chat": { + "editors": [ + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 39, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 1, + "total_chat_insertion_events": 4 + } + ], + "total_engaged_users": 1 + }, + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 134, + "is_custom_model": false, + "total_engaged_users": 16, + "total_chat_copy_events": 24, + "total_chat_insertion_events": 13 + } + ], + "total_engaged_users": 16 + } + ], + "total_engaged_users": 17 + }, + "total_active_users": 26, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 26, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 14, + "total_code_acceptances": 199, + "total_code_suggestions": 853, + "total_code_lines_accepted": 402, + "total_code_lines_suggested": 2805 + }, + { + "name": "unknown", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 2, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 2 + }, + { + "name": "yaml", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 2, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 2 + }, + { + "name": "go", + "total_engaged_users": 4, + "total_code_acceptances": 18, + "total_code_suggestions": 97, + "total_code_lines_accepted": 18, + "total_code_lines_suggested": 152 + }, + { + "name": "xml", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 3, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 5 + } + ], + "is_custom_model": false, + "total_engaged_users": 17 + } + ], + "total_engaged_users": 17 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "json", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 2, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 21 + }, + { + "name": "python", + "total_engaged_users": 2, + "total_code_acceptances": 29, + "total_code_suggestions": 63, + "total_code_lines_accepted": 30, + "total_code_lines_suggested": 83 + }, + { + "name": "shellscript", + "total_engaged_users": 2, + "total_code_acceptances": 7, + "total_code_suggestions": 22, + "total_code_lines_accepted": 7, + "total_code_lines_suggested": 28 + } + ], + "is_custom_model": false, + "total_engaged_users": 2 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 17 + } + }, + { + "date": "2024-11-14", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 54, + "is_custom_model": false, + "total_engaged_users": 8, + "total_chat_copy_events": 21, + "total_chat_insertion_events": 4 + } + ], + "total_engaged_users": 8 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 30, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 9 + }, + "total_active_users": 25, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 25, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 17, + "total_code_acceptances": 240, + "total_code_suggestions": 867, + "total_code_lines_accepted": 410, + "total_code_lines_suggested": 2297 + }, + { + "name": "xml", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 3, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 4 + }, + { + "name": "groovy", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "unknown", + "total_engaged_users": 3, + "total_code_acceptances": 7, + "total_code_suggestions": 52, + "total_code_lines_accepted": 36, + "total_code_lines_suggested": 577 + }, + { + "name": "go", + "total_engaged_users": 3, + "total_code_acceptances": 65, + "total_code_suggestions": 509, + "total_code_lines_accepted": 104, + "total_code_lines_suggested": 1325 + }, + { + "name": "sql", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 3, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 3 + }, + { + "name": "yaml", + "total_engaged_users": 2, + "total_code_acceptances": 1, + "total_code_suggestions": 11, + "total_code_lines_accepted": 47, + "total_code_lines_suggested": 181 + } + ], + "is_custom_model": false, + "total_engaged_users": 19 + } + ], + "total_engaged_users": 19 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "unknown", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "shellscript", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 15, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 16 + } + ], + "is_custom_model": false, + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 19 + } + }, + { + "date": "2024-11-15", + "copilot_ide_chat": { + "editors": [ + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 22, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 4, + "total_chat_insertion_events": 1 + } + ], + "total_engaged_users": 1 + }, + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 36, + "is_custom_model": false, + "total_engaged_users": 8, + "total_chat_copy_events": 4, + "total_chat_insertion_events": 4 + } + ], + "total_engaged_users": 8 + } + ], + "total_engaged_users": 9 + }, + "total_active_users": 22, + "copilot_dotcom_chat": { + "models": [ + { + "name": "default", + "total_chats": 1, + "is_custom_model": false, + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + }, + "total_engaged_users": 22, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "typescript", + "total_engaged_users": 2, + "total_code_acceptances": 7, + "total_code_suggestions": 12, + "total_code_lines_accepted": 7, + "total_code_lines_suggested": 12 + }, + { + "name": "shellscript", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 2, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 3 + } + ], + "is_custom_model": false, + "total_engaged_users": 2 + } + ], + "total_engaged_users": 2 + }, + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 17, + "total_code_acceptances": 322, + "total_code_suggestions": 1090, + "total_code_lines_accepted": 545, + "total_code_lines_suggested": 3699 + }, + { + "name": "go", + "total_engaged_users": 5, + "total_code_acceptances": 37, + "total_code_suggestions": 284, + "total_code_lines_accepted": 41, + "total_code_lines_suggested": 518 + }, + { + "name": "xml", + "total_engaged_users": 2, + "total_code_acceptances": 3, + "total_code_suggestions": 7, + "total_code_lines_accepted": 3, + "total_code_lines_suggested": 15 + }, + { + "name": "unknown", + "total_engaged_users": 2, + "total_code_acceptances": 5, + "total_code_suggestions": 45, + "total_code_lines_accepted": 13, + "total_code_lines_suggested": 468 + }, + { + "name": "yaml", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "sql", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 3, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 7 + } + ], + "is_custom_model": false, + "total_engaged_users": 21 + } + ], + "total_engaged_users": 21 + } + ], + "total_engaged_users": 22 + } + }, + { + "date": "2024-11-16", + "copilot_ide_chat": { + "total_engaged_users": 0 + }, + "total_active_users": 4, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 4, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 4, + "total_code_acceptances": 50, + "total_code_suggestions": 210, + "total_code_lines_accepted": 85, + "total_code_lines_suggested": 577 + }, + { + "name": "groovy", + "total_engaged_users": 2, + "total_code_acceptances": 1, + "total_code_suggestions": 1, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 2 + }, + { + "name": "sql", + "total_engaged_users": 2, + "total_code_acceptances": 1, + "total_code_suggestions": 4, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 15 + } + ], + "is_custom_model": false, + "total_engaged_users": 5 + } + ], + "total_engaged_users": 5 + } + ], + "total_engaged_users": 5 + } + }, + { + "date": "2024-11-17", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 18, + "is_custom_model": false, + "total_engaged_users": 3, + "total_chat_copy_events": 2, + "total_chat_insertion_events": 1 + } + ], + "total_engaged_users": 3 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 72, + "is_custom_model": false, + "total_engaged_users": 2, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 2 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 5 + }, + "total_active_users": 9, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 9, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "yaml", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 2, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 2 + }, + { + "name": "java", + "total_engaged_users": 4, + "total_code_acceptances": 67, + "total_code_suggestions": 234, + "total_code_lines_accepted": 150, + "total_code_lines_suggested": 615 + }, + { + "name": "xml", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 7, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 15 + }, + { + "name": "unknown", + "total_engaged_users": 2, + "total_code_acceptances": 45, + "total_code_suggestions": 279, + "total_code_lines_accepted": 45, + "total_code_lines_suggested": 523 + } + ], + "is_custom_model": false, + "total_engaged_users": 5 + } + ], + "total_engaged_users": 5 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "python", + "total_engaged_users": 2, + "total_code_acceptances": 3, + "total_code_suggestions": 14, + "total_code_lines_accepted": 7, + "total_code_lines_suggested": 28 + }, + { + "name": "rust", + "total_engaged_users": 2, + "total_code_acceptances": 33, + "total_code_suggestions": 79, + "total_code_lines_accepted": 80, + "total_code_lines_suggested": 263 + } + ], + "is_custom_model": false, + "total_engaged_users": 3 + } + ], + "total_engaged_users": 3 + } + ], + "total_engaged_users": 7 + } + }, + { + "date": "2024-11-18", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 122, + "is_custom_model": false, + "total_engaged_users": 13, + "total_chat_copy_events": 47, + "total_chat_insertion_events": 26 + } + ], + "total_engaged_users": 13 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 12, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 4, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 13 + }, + "total_active_users": 28, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 28, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 21, + "total_code_acceptances": 453, + "total_code_suggestions": 0, + "total_code_lines_accepted": 670, + "total_code_lines_suggested": 0 + }, + { + "name": "yaml", + "total_engaged_users": 1, + "total_code_acceptances": 1, + "total_code_suggestions": 0, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 0 + }, + { + "name": "xml", + "total_engaged_users": 3, + "total_code_acceptances": 4, + "total_code_suggestions": 0, + "total_code_lines_accepted": 4, + "total_code_lines_suggested": 0 + }, + { + "name": "ini", + "total_engaged_users": 1, + "total_code_acceptances": 1, + "total_code_suggestions": 0, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 0 + }, + { + "name": "go", + "total_engaged_users": 4, + "total_code_acceptances": 279, + "total_code_suggestions": 0, + "total_code_lines_accepted": 335, + "total_code_lines_suggested": 0 + }, + { + "name": "unknown", + "total_engaged_users": 2, + "total_code_acceptances": 3, + "total_code_suggestions": 0, + "total_code_lines_accepted": 3, + "total_code_lines_suggested": 0 + } + ], + "is_custom_model": false, + "total_engaged_users": 25 + } + ], + "total_engaged_users": 25 + } + ], + "languages": [ + { + "name": "java", + "total_engaged_users": 21 + }, + { + "name": "yaml", + "total_engaged_users": 1 + }, + { + "name": "xml", + "total_engaged_users": 3 + }, + { + "name": "ini", + "total_engaged_users": 1 + }, + { + "name": "go", + "total_engaged_users": 4 + }, + { + "name": "unknown", + "total_engaged_users": 2 + } + ], + "total_engaged_users": 25 + } + }, + { + "date": "2024-11-19", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 86, + "is_custom_model": false, + "total_engaged_users": 9, + "total_chat_copy_events": 21, + "total_chat_insertion_events": 19 + } + ], + "total_engaged_users": 9 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 25, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 10 + }, + "total_active_users": 29, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 29, + "copilot_dotcom_pull_requests": { + "repositories": [ + { + "name": "", + "models": [ + { + "name": "default", + "is_custom_model": false, + "total_engaged_users": 1, + "total_pr_summaries_created": 1 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 20, + "total_code_acceptances": 519, + "total_code_suggestions": 0, + "total_code_lines_accepted": 1050, + "total_code_lines_suggested": 0 + }, + { + "name": "yaml", + "total_engaged_users": 2, + "total_code_acceptances": 12, + "total_code_suggestions": 0, + "total_code_lines_accepted": 14, + "total_code_lines_suggested": 0 + }, + { + "name": "go", + "total_engaged_users": 4, + "total_code_acceptances": 248, + "total_code_suggestions": 0, + "total_code_lines_accepted": 309, + "total_code_lines_suggested": 0 + }, + { + "name": "ini", + "total_engaged_users": 1, + "total_code_acceptances": 2, + "total_code_suggestions": 0, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 0 + }, + { + "name": "unknown", + "total_engaged_users": 1, + "total_code_acceptances": 5, + "total_code_suggestions": 0, + "total_code_lines_accepted": 21, + "total_code_lines_suggested": 0 + } + ], + "is_custom_model": false, + "total_engaged_users": 24 + } + ], + "total_engaged_users": 24 + } + ], + "languages": [ + { + "name": "java", + "total_engaged_users": 20 + }, + { + "name": "go", + "total_engaged_users": 4 + }, + { + "name": "yaml", + "total_engaged_users": 2 + }, + { + "name": "ini", + "total_engaged_users": 1 + }, + { + "name": "unknown", + "total_engaged_users": 1 + } + ], + "total_engaged_users": 24 + } + }, + { + "date": "2024-11-20", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 120, + "is_custom_model": false, + "total_engaged_users": 11, + "total_chat_copy_events": 34, + "total_chat_insertion_events": 20 + } + ], + "total_engaged_users": 11 + } + ], + "total_engaged_users": 11 + }, + "total_active_users": 25, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 25, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 19, + "total_code_acceptances": 431, + "total_code_suggestions": 1397, + "total_code_lines_accepted": 671, + "total_code_lines_suggested": 3855 + }, + { + "name": "xml", + "total_engaged_users": 6, + "total_code_acceptances": 45, + "total_code_suggestions": 90, + "total_code_lines_accepted": 83, + "total_code_lines_suggested": 232 + }, + { + "name": "ini", + "total_engaged_users": 1, + "total_code_acceptances": 4, + "total_code_suggestions": 7, + "total_code_lines_accepted": 4, + "total_code_lines_suggested": 13 + }, + { + "name": "go", + "total_engaged_users": 4, + "total_code_acceptances": 60, + "total_code_suggestions": 328, + "total_code_lines_accepted": 94, + "total_code_lines_suggested": 704 + }, + { + "name": "sql", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 21, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 34 + }, + { + "name": "yaml", + "total_engaged_users": 1, + "total_code_acceptances": 1, + "total_code_suggestions": 15, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 25 + }, + { + "name": "unknown", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 6, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 15 + } + ], + "is_custom_model": false, + "total_engaged_users": 24 + } + ], + "total_engaged_users": 24 + } + ], + "languages": [ + { + "name": "java", + "total_engaged_users": 19 + }, + { + "name": "xml", + "total_engaged_users": 6 + }, + { + "name": "ini", + "total_engaged_users": 1 + }, + { + "name": "sql", + "total_engaged_users": 0 + }, + { + "name": "go", + "total_engaged_users": 4 + }, + { + "name": "yaml", + "total_engaged_users": 1 + }, + { + "name": "unknown", + "total_engaged_users": 2 + } + ], + "total_engaged_users": 24 + } + }, + { + "date": "2024-11-21", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 130, + "is_custom_model": false, + "total_engaged_users": 9, + "total_chat_copy_events": 39, + "total_chat_insertion_events": 19 + } + ], + "total_engaged_users": 9 + } + ], + "total_engaged_users": 9 + }, + "total_active_users": 26, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 25, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 21, + "total_code_acceptances": 453, + "total_code_suggestions": 1655, + "total_code_lines_accepted": 779, + "total_code_lines_suggested": 5707 + }, + { + "name": "sql", + "total_engaged_users": 1, + "total_code_acceptances": 1, + "total_code_suggestions": 8, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 13 + }, + { + "name": "yaml", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 27, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 101 + }, + { + "name": "go", + "total_engaged_users": 4, + "total_code_acceptances": 104, + "total_code_suggestions": 370, + "total_code_lines_accepted": 123, + "total_code_lines_suggested": 883 + }, + { + "name": "xml", + "total_engaged_users": 3, + "total_code_acceptances": 7, + "total_code_suggestions": 18, + "total_code_lines_accepted": 9, + "total_code_lines_suggested": 48 + }, + { + "name": "unknown", + "total_engaged_users": 2, + "total_code_acceptances": 38, + "total_code_suggestions": 122, + "total_code_lines_accepted": 72, + "total_code_lines_suggested": 560 + }, + { + "name": "ini", + "total_engaged_users": 1, + "total_code_acceptances": 2, + "total_code_suggestions": 8, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 15 + }, + { + "name": "shellscript", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 6, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 9 + } + ], + "is_custom_model": false, + "total_engaged_users": 25 + } + ], + "total_engaged_users": 25 + } + ], + "languages": [ + { + "name": "java", + "total_engaged_users": 21 + }, + { + "name": "sql", + "total_engaged_users": 1 + }, + { + "name": "go", + "total_engaged_users": 4 + }, + { + "name": "yaml", + "total_engaged_users": 0 + }, + { + "name": "xml", + "total_engaged_users": 3 + }, + { + "name": "unknown", + "total_engaged_users": 2 + }, + { + "name": "ini", + "total_engaged_users": 1 + }, + { + "name": "shellscript", + "total_engaged_users": 0 + } + ], + "total_engaged_users": 25 + } + }, + { + "date": "2024-11-22", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 32, + "is_custom_model": false, + "total_engaged_users": 6, + "total_chat_copy_events": 9, + "total_chat_insertion_events": 6 + } + ], + "total_engaged_users": 6 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 42, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 1, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 7 + }, + "total_active_users": 24, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 20, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 15, + "total_code_acceptances": 114, + "total_code_suggestions": 594, + "total_code_lines_accepted": 191, + "total_code_lines_suggested": 1425 + }, + { + "name": "go", + "total_engaged_users": 4, + "total_code_acceptances": 39, + "total_code_suggestions": 189, + "total_code_lines_accepted": 47, + "total_code_lines_suggested": 424 + }, + { + "name": "xml", + "total_engaged_users": 1, + "total_code_acceptances": 1, + "total_code_suggestions": 8, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 18 + }, + { + "name": "json", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "unknown", + "total_engaged_users": 1, + "total_code_acceptances": 3, + "total_code_suggestions": 79, + "total_code_lines_accepted": 3, + "total_code_lines_suggested": 179 + }, + { + "name": "sql", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + } + ], + "is_custom_model": false, + "total_engaged_users": 19 + } + ], + "total_engaged_users": 19 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "rust", + "total_engaged_users": 1, + "total_code_acceptances": 34, + "total_code_suggestions": 139, + "total_code_lines_accepted": 38, + "total_code_lines_suggested": 472 + }, + { + "name": "unknown", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + } + ], + "is_custom_model": false, + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + } + ], + "languages": [ + { + "name": "java", + "total_engaged_users": 15 + }, + { + "name": "go", + "total_engaged_users": 4 + }, + { + "name": "xml", + "total_engaged_users": 1 + }, + { + "name": "json", + "total_engaged_users": 0 + }, + { + "name": "unknown", + "total_engaged_users": 1 + }, + { + "name": "sql", + "total_engaged_users": 0 + }, + { + "name": "rust", + "total_engaged_users": 1 + } + ], + "total_engaged_users": 19 + } + }, + { + "date": "2024-11-23", + "copilot_ide_chat": { + "total_engaged_users": 0 + }, + "total_active_users": 1, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 1, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 1, + "total_code_acceptances": 19, + "total_code_suggestions": 59, + "total_code_lines_accepted": 38, + "total_code_lines_suggested": 183 + }, + { + "name": "xml", + "total_engaged_users": 1, + "total_code_acceptances": 2, + "total_code_suggestions": 2, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 5 + } + ], + "is_custom_model": false, + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + } + ], + "languages": [ + { + "name": "java", + "total_engaged_users": 1 + }, + { + "name": "xml", + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + } + }, + { + "date": "2024-11-24", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 12, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 4, + "total_chat_insertion_events": 3 + } + ], + "total_engaged_users": 1 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 3, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 2 + }, + "total_active_users": 7, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 7, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 6, + "total_code_acceptances": 52, + "total_code_suggestions": 279, + "total_code_lines_accepted": 113, + "total_code_lines_suggested": 776 + }, + { + "name": "xml", + "total_engaged_users": 2, + "total_code_acceptances": 9, + "total_code_suggestions": 23, + "total_code_lines_accepted": 9, + "total_code_lines_suggested": 61 + }, + { + "name": "sql", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "yaml", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 2, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 4 + } + ], + "is_custom_model": false, + "total_engaged_users": 6 + } + ], + "total_engaged_users": 6 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 1, + "total_code_acceptances": 1, + "total_code_suggestions": 1, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 1 + }, + { + "name": "xml", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 10 + } + ], + "is_custom_model": false, + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + } + ], + "languages": [ + { + "name": "java", + "total_engaged_users": 7 + }, + { + "name": "xml", + "total_engaged_users": 2 + }, + { + "name": "sql", + "total_engaged_users": 0 + }, + { + "name": "yaml", + "total_engaged_users": 0 + } + ], + "total_engaged_users": 7 + } + } +] \ No newline at end of file diff --git a/mock-data/enterprise_response_sample_seats.json b/mock-data/enterprise_seats_response_sample.json similarity index 100% rename from mock-data/enterprise_response_sample_seats.json rename to mock-data/enterprise_seats_response_sample.json diff --git a/mock-data/enterprise_response_sample.json b/mock-data/enterprise_usage_response_sample.json similarity index 100% rename from mock-data/enterprise_response_sample.json rename to mock-data/enterprise_usage_response_sample.json diff --git a/mock-data/organization_metrics_response_sample.json b/mock-data/organization_metrics_response_sample.json new file mode 100644 index 0000000..37a8b36 --- /dev/null +++ b/mock-data/organization_metrics_response_sample.json @@ -0,0 +1,2504 @@ +[ + { + "date": "2024-11-04", + "copilot_ide_chat": { + "editors": [ + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 34, + "is_custom_model": false, + "total_engaged_users": 2, + "total_chat_copy_events": 1, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 2 + }, + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 10, + "is_custom_model": false, + "total_engaged_users": 2, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 1 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 4 + }, + "total_active_users": 4, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 4, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "kotlin", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 3, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 11 + }, + { + "name": "json", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 37 + }, + { + "name": "python", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 2, + "total_code_lines_accepted": 12, + "total_code_lines_suggested": 13 + } + ], + "is_custom_model": false, + "total_engaged_users": 2 + } + ], + "total_engaged_users": 2 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "python", + "total_engaged_users": 2, + "total_code_acceptances": 9, + "total_code_suggestions": 15, + "total_code_lines_accepted": 8, + "total_code_lines_suggested": 21 + } + ], + "is_custom_model": false, + "total_engaged_users": 2 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 3 + } + }, + { + "date": "2024-11-05", + "copilot_ide_chat": { + "editors": [ + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 12, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + }, + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 18, + "is_custom_model": false, + "total_engaged_users": 2, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 3 + }, + "total_active_users": 3, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 3, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "kotlin", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "go", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 3, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 3 + } + ], + "is_custom_model": false, + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + } + }, + { + "date": "2024-11-06", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 231, + "is_custom_model": false, + "total_engaged_users": 17, + "total_chat_copy_events": 69, + "total_chat_insertion_events": 23 + } + ], + "total_engaged_users": 17 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 30, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 18 + }, + "total_active_users": 29, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 29, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 20, + "total_code_acceptances": 345, + "total_code_suggestions": 1357, + "total_code_lines_accepted": 613, + "total_code_lines_suggested": 4843 + }, + { + "name": "groovy", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "go", + "total_engaged_users": 5, + "total_code_acceptances": 148, + "total_code_suggestions": 838, + "total_code_lines_accepted": 226, + "total_code_lines_suggested": 1860 + }, + { + "name": "xml", + "total_engaged_users": 4, + "total_code_acceptances": 10, + "total_code_suggestions": 34, + "total_code_lines_accepted": 11, + "total_code_lines_suggested": 98 + }, + { + "name": "json", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 3, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 3 + }, + { + "name": "sql", + "total_engaged_users": 2, + "total_code_acceptances": 4, + "total_code_suggestions": 71, + "total_code_lines_accepted": 4, + "total_code_lines_suggested": 149 + }, + { + "name": "yaml", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "unknown", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 3, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 5 + } + ], + "is_custom_model": false, + "total_engaged_users": 24 + } + ], + "total_engaged_users": 24 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "python", + "total_engaged_users": 2, + "total_code_acceptances": 16, + "total_code_suggestions": 41, + "total_code_lines_accepted": 14, + "total_code_lines_suggested": 59 + } + ], + "is_custom_model": false, + "total_engaged_users": 2 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 25 + } + }, + { + "date": "2024-11-07", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 245, + "is_custom_model": false, + "total_engaged_users": 16, + "total_chat_copy_events": 64, + "total_chat_insertion_events": 40 + } + ], + "total_engaged_users": 16 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 18, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 16 + }, + "total_active_users": 27, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 27, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 18, + "total_code_acceptances": 356, + "total_code_suggestions": 1204, + "total_code_lines_accepted": 599, + "total_code_lines_suggested": 3270 + }, + { + "name": "xml", + "total_engaged_users": 3, + "total_code_acceptances": 3, + "total_code_suggestions": 15, + "total_code_lines_accepted": 6, + "total_code_lines_suggested": 45 + }, + { + "name": "sql", + "total_engaged_users": 2, + "total_code_acceptances": 3, + "total_code_suggestions": 12, + "total_code_lines_accepted": 3, + "total_code_lines_suggested": 33 + }, + { + "name": "go", + "total_engaged_users": 5, + "total_code_acceptances": 305, + "total_code_suggestions": 1185, + "total_code_lines_accepted": 495, + "total_code_lines_suggested": 2773 + }, + { + "name": "unknown", + "total_engaged_users": 3, + "total_code_acceptances": 5, + "total_code_suggestions": 68, + "total_code_lines_accepted": 14, + "total_code_lines_suggested": 147 + }, + { + "name": "yaml", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 3, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 3 + }, + { + "name": "shellscript", + "total_engaged_users": 2, + "total_code_acceptances": 1, + "total_code_suggestions": 1, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 2 + }, + { + "name": "groovy", + "total_engaged_users": 2, + "total_code_acceptances": 3, + "total_code_suggestions": 12, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 28 + } + ], + "is_custom_model": false, + "total_engaged_users": 23 + } + ], + "total_engaged_users": 23 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "cpp", + "total_engaged_users": 2, + "total_code_acceptances": 9, + "total_code_suggestions": 13, + "total_code_lines_accepted": 9, + "total_code_lines_suggested": 13 + }, + { + "name": "typescript", + "total_engaged_users": 2, + "total_code_acceptances": 6, + "total_code_suggestions": 12, + "total_code_lines_accepted": 5, + "total_code_lines_suggested": 13 + } + ], + "is_custom_model": false, + "total_engaged_users": 2 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 24 + } + }, + { + "date": "2024-11-08", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 86, + "is_custom_model": false, + "total_engaged_users": 11, + "total_chat_copy_events": 15, + "total_chat_insertion_events": 9 + } + ], + "total_engaged_users": 11 + } + ], + "total_engaged_users": 11 + }, + "total_active_users": 21, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 21, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "go", + "total_engaged_users": 5, + "total_code_acceptances": 207, + "total_code_suggestions": 860, + "total_code_lines_accepted": 312, + "total_code_lines_suggested": 2589 + }, + { + "name": "unknown", + "total_engaged_users": 4, + "total_code_acceptances": 17, + "total_code_suggestions": 91, + "total_code_lines_accepted": 28, + "total_code_lines_suggested": 472 + }, + { + "name": "java", + "total_engaged_users": 14, + "total_code_acceptances": 158, + "total_code_suggestions": 604, + "total_code_lines_accepted": 269, + "total_code_lines_suggested": 1874 + }, + { + "name": "xml", + "total_engaged_users": 3, + "total_code_acceptances": 9, + "total_code_suggestions": 33, + "total_code_lines_accepted": 13, + "total_code_lines_suggested": 129 + }, + { + "name": "sql", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "groovy", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 5, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 19 + } + ], + "is_custom_model": false, + "total_engaged_users": 19 + } + ], + "total_engaged_users": 19 + } + ], + "total_engaged_users": 19 + } + }, + { + "date": "2024-11-09", + "copilot_ide_chat": { + "editors": [ + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 128, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 9, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + }, + "total_active_users": 1, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 1, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "rust", + "total_engaged_users": 2, + "total_code_acceptances": 38, + "total_code_suggestions": 175, + "total_code_lines_accepted": 43, + "total_code_lines_suggested": 529 + }, + { + "name": "unknown", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + } + ], + "is_custom_model": false, + "total_engaged_users": 2 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 2 + } + }, + { + "date": "2024-11-10", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 6, + "is_custom_model": false, + "total_engaged_users": 2, + "total_chat_copy_events": 2, + "total_chat_insertion_events": 1 + } + ], + "total_engaged_users": 2 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 3, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 2 + }, + "total_active_users": 5, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 5, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "go", + "total_engaged_users": 2, + "total_code_acceptances": 26, + "total_code_suggestions": 94, + "total_code_lines_accepted": 27, + "total_code_lines_suggested": 192 + }, + { + "name": "java", + "total_engaged_users": 3, + "total_code_acceptances": 8, + "total_code_suggestions": 55, + "total_code_lines_accepted": 9, + "total_code_lines_suggested": 252 + } + ], + "is_custom_model": false, + "total_engaged_users": 4 + } + ], + "total_engaged_users": 4 + } + ], + "total_engaged_users": 4 + } + }, + { + "date": "2024-11-11", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 90, + "is_custom_model": false, + "total_engaged_users": 11, + "total_chat_copy_events": 34, + "total_chat_insertion_events": 24 + } + ], + "total_engaged_users": 11 + } + ], + "total_engaged_users": 11 + }, + "total_active_users": 23, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 23, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 15, + "total_code_acceptances": 241, + "total_code_suggestions": 1073, + "total_code_lines_accepted": 396, + "total_code_lines_suggested": 3252 + }, + { + "name": "xml", + "total_engaged_users": 4, + "total_code_acceptances": 6, + "total_code_suggestions": 22, + "total_code_lines_accepted": 7, + "total_code_lines_suggested": 70 + }, + { + "name": "go", + "total_engaged_users": 5, + "total_code_acceptances": 160, + "total_code_suggestions": 1086, + "total_code_lines_accepted": 177, + "total_code_lines_suggested": 2498 + }, + { + "name": "unknown", + "total_engaged_users": 3, + "total_code_acceptances": 6, + "total_code_suggestions": 58, + "total_code_lines_accepted": 6, + "total_code_lines_suggested": 99 + }, + { + "name": "yaml", + "total_engaged_users": 2, + "total_code_acceptances": 1, + "total_code_suggestions": 7, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 18 + }, + { + "name": "groovy", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 3, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 20 + } + ], + "is_custom_model": false, + "total_engaged_users": 20 + } + ], + "total_engaged_users": 20 + } + ], + "total_engaged_users": 20 + } + }, + { + "date": "2024-11-12", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 78, + "is_custom_model": false, + "total_engaged_users": 9, + "total_chat_copy_events": 24, + "total_chat_insertion_events": 14 + } + ], + "total_engaged_users": 9 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 57, + "is_custom_model": false, + "total_engaged_users": 2, + "total_chat_copy_events": 1, + "total_chat_insertion_events": 2 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 11 + }, + "total_active_users": 26, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 26, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 18, + "total_code_acceptances": 275, + "total_code_suggestions": 1059, + "total_code_lines_accepted": 444, + "total_code_lines_suggested": 3152 + }, + { + "name": "go", + "total_engaged_users": 5, + "total_code_acceptances": 142, + "total_code_suggestions": 725, + "total_code_lines_accepted": 183, + "total_code_lines_suggested": 1687 + }, + { + "name": "xml", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 11, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 18 + }, + { + "name": "yaml", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 13, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 33 + }, + { + "name": "unknown", + "total_engaged_users": 4, + "total_code_acceptances": 3, + "total_code_suggestions": 31, + "total_code_lines_accepted": 3, + "total_code_lines_suggested": 79 + } + ], + "is_custom_model": false, + "total_engaged_users": 23 + } + ], + "total_engaged_users": 23 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "typescript", + "total_engaged_users": 2, + "total_code_acceptances": 10, + "total_code_suggestions": 22, + "total_code_lines_accepted": 12, + "total_code_lines_suggested": 29 + }, + { + "name": "json", + "total_engaged_users": 2, + "total_code_acceptances": 1, + "total_code_suggestions": 1, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 1 + }, + { + "name": "unknown", + "total_engaged_users": 2, + "total_code_acceptances": 1, + "total_code_suggestions": 7, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 9 + }, + { + "name": "python", + "total_engaged_users": 2, + "total_code_acceptances": 28, + "total_code_suggestions": 81, + "total_code_lines_accepted": 33, + "total_code_lines_suggested": 101 + } + ], + "is_custom_model": false, + "total_engaged_users": 3 + } + ], + "total_engaged_users": 3 + } + ], + "total_engaged_users": 24 + } + }, + { + "date": "2024-11-13", + "copilot_ide_chat": { + "editors": [ + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 39, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 1, + "total_chat_insertion_events": 4 + } + ], + "total_engaged_users": 1 + }, + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 134, + "is_custom_model": false, + "total_engaged_users": 16, + "total_chat_copy_events": 24, + "total_chat_insertion_events": 13 + } + ], + "total_engaged_users": 16 + } + ], + "total_engaged_users": 17 + }, + "total_active_users": 26, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 26, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 14, + "total_code_acceptances": 199, + "total_code_suggestions": 853, + "total_code_lines_accepted": 402, + "total_code_lines_suggested": 2805 + }, + { + "name": "unknown", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 2, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 2 + }, + { + "name": "yaml", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 2, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 2 + }, + { + "name": "go", + "total_engaged_users": 4, + "total_code_acceptances": 18, + "total_code_suggestions": 97, + "total_code_lines_accepted": 18, + "total_code_lines_suggested": 152 + }, + { + "name": "xml", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 3, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 5 + } + ], + "is_custom_model": false, + "total_engaged_users": 17 + } + ], + "total_engaged_users": 17 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "json", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 2, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 21 + }, + { + "name": "python", + "total_engaged_users": 2, + "total_code_acceptances": 29, + "total_code_suggestions": 63, + "total_code_lines_accepted": 30, + "total_code_lines_suggested": 83 + }, + { + "name": "shellscript", + "total_engaged_users": 2, + "total_code_acceptances": 7, + "total_code_suggestions": 22, + "total_code_lines_accepted": 7, + "total_code_lines_suggested": 28 + } + ], + "is_custom_model": false, + "total_engaged_users": 2 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 17 + } + }, + { + "date": "2024-11-14", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 54, + "is_custom_model": false, + "total_engaged_users": 8, + "total_chat_copy_events": 21, + "total_chat_insertion_events": 4 + } + ], + "total_engaged_users": 8 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 30, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 9 + }, + "total_active_users": 25, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 25, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 17, + "total_code_acceptances": 240, + "total_code_suggestions": 867, + "total_code_lines_accepted": 410, + "total_code_lines_suggested": 2297 + }, + { + "name": "xml", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 3, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 4 + }, + { + "name": "groovy", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "unknown", + "total_engaged_users": 3, + "total_code_acceptances": 7, + "total_code_suggestions": 52, + "total_code_lines_accepted": 36, + "total_code_lines_suggested": 577 + }, + { + "name": "go", + "total_engaged_users": 3, + "total_code_acceptances": 65, + "total_code_suggestions": 509, + "total_code_lines_accepted": 104, + "total_code_lines_suggested": 1325 + }, + { + "name": "sql", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 3, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 3 + }, + { + "name": "yaml", + "total_engaged_users": 2, + "total_code_acceptances": 1, + "total_code_suggestions": 11, + "total_code_lines_accepted": 47, + "total_code_lines_suggested": 181 + } + ], + "is_custom_model": false, + "total_engaged_users": 19 + } + ], + "total_engaged_users": 19 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "unknown", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "shellscript", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 15, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 16 + } + ], + "is_custom_model": false, + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 19 + } + }, + { + "date": "2024-11-15", + "copilot_ide_chat": { + "editors": [ + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 22, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 4, + "total_chat_insertion_events": 1 + } + ], + "total_engaged_users": 1 + }, + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 36, + "is_custom_model": false, + "total_engaged_users": 8, + "total_chat_copy_events": 4, + "total_chat_insertion_events": 4 + } + ], + "total_engaged_users": 8 + } + ], + "total_engaged_users": 9 + }, + "total_active_users": 22, + "copilot_dotcom_chat": { + "models": [ + { + "name": "default", + "total_chats": 1, + "is_custom_model": false, + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + }, + "total_engaged_users": 22, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "typescript", + "total_engaged_users": 2, + "total_code_acceptances": 7, + "total_code_suggestions": 12, + "total_code_lines_accepted": 7, + "total_code_lines_suggested": 12 + }, + { + "name": "shellscript", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 2, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 3 + } + ], + "is_custom_model": false, + "total_engaged_users": 2 + } + ], + "total_engaged_users": 2 + }, + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 17, + "total_code_acceptances": 322, + "total_code_suggestions": 1090, + "total_code_lines_accepted": 545, + "total_code_lines_suggested": 3699 + }, + { + "name": "go", + "total_engaged_users": 5, + "total_code_acceptances": 37, + "total_code_suggestions": 284, + "total_code_lines_accepted": 41, + "total_code_lines_suggested": 518 + }, + { + "name": "xml", + "total_engaged_users": 2, + "total_code_acceptances": 3, + "total_code_suggestions": 7, + "total_code_lines_accepted": 3, + "total_code_lines_suggested": 15 + }, + { + "name": "unknown", + "total_engaged_users": 2, + "total_code_acceptances": 5, + "total_code_suggestions": 45, + "total_code_lines_accepted": 13, + "total_code_lines_suggested": 468 + }, + { + "name": "yaml", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "sql", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 3, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 7 + } + ], + "is_custom_model": false, + "total_engaged_users": 21 + } + ], + "total_engaged_users": 21 + } + ], + "total_engaged_users": 22 + } + }, + { + "date": "2024-11-16", + "copilot_ide_chat": { + "total_engaged_users": 0 + }, + "total_active_users": 4, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 4, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 4, + "total_code_acceptances": 50, + "total_code_suggestions": 210, + "total_code_lines_accepted": 85, + "total_code_lines_suggested": 577 + }, + { + "name": "groovy", + "total_engaged_users": 2, + "total_code_acceptances": 1, + "total_code_suggestions": 1, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 2 + }, + { + "name": "sql", + "total_engaged_users": 2, + "total_code_acceptances": 1, + "total_code_suggestions": 4, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 15 + } + ], + "is_custom_model": false, + "total_engaged_users": 5 + } + ], + "total_engaged_users": 5 + } + ], + "total_engaged_users": 5 + } + }, + { + "date": "2024-11-17", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 18, + "is_custom_model": false, + "total_engaged_users": 3, + "total_chat_copy_events": 2, + "total_chat_insertion_events": 1 + } + ], + "total_engaged_users": 3 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 72, + "is_custom_model": false, + "total_engaged_users": 2, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 2 + } + ], + "total_engaged_users": 2 + } + ], + "total_engaged_users": 5 + }, + "total_active_users": 9, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 9, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "yaml", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 2, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 2 + }, + { + "name": "java", + "total_engaged_users": 4, + "total_code_acceptances": 67, + "total_code_suggestions": 234, + "total_code_lines_accepted": 150, + "total_code_lines_suggested": 615 + }, + { + "name": "xml", + "total_engaged_users": 1, + "total_code_acceptances": 0, + "total_code_suggestions": 7, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 15 + }, + { + "name": "unknown", + "total_engaged_users": 2, + "total_code_acceptances": 45, + "total_code_suggestions": 279, + "total_code_lines_accepted": 45, + "total_code_lines_suggested": 523 + } + ], + "is_custom_model": false, + "total_engaged_users": 5 + } + ], + "total_engaged_users": 5 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "python", + "total_engaged_users": 2, + "total_code_acceptances": 3, + "total_code_suggestions": 14, + "total_code_lines_accepted": 7, + "total_code_lines_suggested": 28 + }, + { + "name": "rust", + "total_engaged_users": 2, + "total_code_acceptances": 33, + "total_code_suggestions": 79, + "total_code_lines_accepted": 80, + "total_code_lines_suggested": 263 + } + ], + "is_custom_model": false, + "total_engaged_users": 3 + } + ], + "total_engaged_users": 3 + } + ], + "total_engaged_users": 7 + } + }, + { + "date": "2024-11-18", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 122, + "is_custom_model": false, + "total_engaged_users": 13, + "total_chat_copy_events": 47, + "total_chat_insertion_events": 26 + } + ], + "total_engaged_users": 13 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 12, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 4, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 13 + }, + "total_active_users": 28, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 28, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 21, + "total_code_acceptances": 453, + "total_code_suggestions": 0, + "total_code_lines_accepted": 670, + "total_code_lines_suggested": 0 + }, + { + "name": "yaml", + "total_engaged_users": 1, + "total_code_acceptances": 1, + "total_code_suggestions": 0, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 0 + }, + { + "name": "xml", + "total_engaged_users": 3, + "total_code_acceptances": 4, + "total_code_suggestions": 0, + "total_code_lines_accepted": 4, + "total_code_lines_suggested": 0 + }, + { + "name": "ini", + "total_engaged_users": 1, + "total_code_acceptances": 1, + "total_code_suggestions": 0, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 0 + }, + { + "name": "go", + "total_engaged_users": 4, + "total_code_acceptances": 279, + "total_code_suggestions": 0, + "total_code_lines_accepted": 335, + "total_code_lines_suggested": 0 + }, + { + "name": "unknown", + "total_engaged_users": 2, + "total_code_acceptances": 3, + "total_code_suggestions": 0, + "total_code_lines_accepted": 3, + "total_code_lines_suggested": 0 + } + ], + "is_custom_model": false, + "total_engaged_users": 25 + } + ], + "total_engaged_users": 25 + } + ], + "languages": [ + { + "name": "java", + "total_engaged_users": 21 + }, + { + "name": "yaml", + "total_engaged_users": 1 + }, + { + "name": "xml", + "total_engaged_users": 3 + }, + { + "name": "ini", + "total_engaged_users": 1 + }, + { + "name": "go", + "total_engaged_users": 4 + }, + { + "name": "unknown", + "total_engaged_users": 2 + } + ], + "total_engaged_users": 25 + } + }, + { + "date": "2024-11-19", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 86, + "is_custom_model": false, + "total_engaged_users": 9, + "total_chat_copy_events": 21, + "total_chat_insertion_events": 19 + } + ], + "total_engaged_users": 9 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 25, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 10 + }, + "total_active_users": 29, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 29, + "copilot_dotcom_pull_requests": { + "repositories": [ + { + "name": "", + "models": [ + { + "name": "default", + "is_custom_model": false, + "total_engaged_users": 1, + "total_pr_summaries_created": 1 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 20, + "total_code_acceptances": 519, + "total_code_suggestions": 0, + "total_code_lines_accepted": 1050, + "total_code_lines_suggested": 0 + }, + { + "name": "yaml", + "total_engaged_users": 2, + "total_code_acceptances": 12, + "total_code_suggestions": 0, + "total_code_lines_accepted": 14, + "total_code_lines_suggested": 0 + }, + { + "name": "go", + "total_engaged_users": 4, + "total_code_acceptances": 248, + "total_code_suggestions": 0, + "total_code_lines_accepted": 309, + "total_code_lines_suggested": 0 + }, + { + "name": "ini", + "total_engaged_users": 1, + "total_code_acceptances": 2, + "total_code_suggestions": 0, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 0 + }, + { + "name": "unknown", + "total_engaged_users": 1, + "total_code_acceptances": 5, + "total_code_suggestions": 0, + "total_code_lines_accepted": 21, + "total_code_lines_suggested": 0 + } + ], + "is_custom_model": false, + "total_engaged_users": 24 + } + ], + "total_engaged_users": 24 + } + ], + "languages": [ + { + "name": "java", + "total_engaged_users": 20 + }, + { + "name": "go", + "total_engaged_users": 4 + }, + { + "name": "yaml", + "total_engaged_users": 2 + }, + { + "name": "ini", + "total_engaged_users": 1 + }, + { + "name": "unknown", + "total_engaged_users": 1 + } + ], + "total_engaged_users": 24 + } + }, + { + "date": "2024-11-20", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 120, + "is_custom_model": false, + "total_engaged_users": 11, + "total_chat_copy_events": 34, + "total_chat_insertion_events": 20 + } + ], + "total_engaged_users": 11 + } + ], + "total_engaged_users": 11 + }, + "total_active_users": 25, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 25, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 19, + "total_code_acceptances": 431, + "total_code_suggestions": 1397, + "total_code_lines_accepted": 671, + "total_code_lines_suggested": 3855 + }, + { + "name": "xml", + "total_engaged_users": 6, + "total_code_acceptances": 45, + "total_code_suggestions": 90, + "total_code_lines_accepted": 83, + "total_code_lines_suggested": 232 + }, + { + "name": "ini", + "total_engaged_users": 1, + "total_code_acceptances": 4, + "total_code_suggestions": 7, + "total_code_lines_accepted": 4, + "total_code_lines_suggested": 13 + }, + { + "name": "go", + "total_engaged_users": 4, + "total_code_acceptances": 60, + "total_code_suggestions": 328, + "total_code_lines_accepted": 94, + "total_code_lines_suggested": 704 + }, + { + "name": "sql", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 21, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 34 + }, + { + "name": "yaml", + "total_engaged_users": 1, + "total_code_acceptances": 1, + "total_code_suggestions": 15, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 25 + }, + { + "name": "unknown", + "total_engaged_users": 2, + "total_code_acceptances": 2, + "total_code_suggestions": 6, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 15 + } + ], + "is_custom_model": false, + "total_engaged_users": 24 + } + ], + "total_engaged_users": 24 + } + ], + "languages": [ + { + "name": "java", + "total_engaged_users": 19 + }, + { + "name": "xml", + "total_engaged_users": 6 + }, + { + "name": "ini", + "total_engaged_users": 1 + }, + { + "name": "sql", + "total_engaged_users": 0 + }, + { + "name": "go", + "total_engaged_users": 4 + }, + { + "name": "yaml", + "total_engaged_users": 1 + }, + { + "name": "unknown", + "total_engaged_users": 2 + } + ], + "total_engaged_users": 24 + } + }, + { + "date": "2024-11-21", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 130, + "is_custom_model": false, + "total_engaged_users": 9, + "total_chat_copy_events": 39, + "total_chat_insertion_events": 19 + } + ], + "total_engaged_users": 9 + } + ], + "total_engaged_users": 9 + }, + "total_active_users": 26, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 25, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 21, + "total_code_acceptances": 453, + "total_code_suggestions": 1655, + "total_code_lines_accepted": 779, + "total_code_lines_suggested": 5707 + }, + { + "name": "sql", + "total_engaged_users": 1, + "total_code_acceptances": 1, + "total_code_suggestions": 8, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 13 + }, + { + "name": "yaml", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 27, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 101 + }, + { + "name": "go", + "total_engaged_users": 4, + "total_code_acceptances": 104, + "total_code_suggestions": 370, + "total_code_lines_accepted": 123, + "total_code_lines_suggested": 883 + }, + { + "name": "xml", + "total_engaged_users": 3, + "total_code_acceptances": 7, + "total_code_suggestions": 18, + "total_code_lines_accepted": 9, + "total_code_lines_suggested": 48 + }, + { + "name": "unknown", + "total_engaged_users": 2, + "total_code_acceptances": 38, + "total_code_suggestions": 122, + "total_code_lines_accepted": 72, + "total_code_lines_suggested": 560 + }, + { + "name": "ini", + "total_engaged_users": 1, + "total_code_acceptances": 2, + "total_code_suggestions": 8, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 15 + }, + { + "name": "shellscript", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 6, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 9 + } + ], + "is_custom_model": false, + "total_engaged_users": 25 + } + ], + "total_engaged_users": 25 + } + ], + "languages": [ + { + "name": "java", + "total_engaged_users": 21 + }, + { + "name": "sql", + "total_engaged_users": 1 + }, + { + "name": "go", + "total_engaged_users": 4 + }, + { + "name": "yaml", + "total_engaged_users": 0 + }, + { + "name": "xml", + "total_engaged_users": 3 + }, + { + "name": "unknown", + "total_engaged_users": 2 + }, + { + "name": "ini", + "total_engaged_users": 1 + }, + { + "name": "shellscript", + "total_engaged_users": 0 + } + ], + "total_engaged_users": 25 + } + }, + { + "date": "2024-11-22", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 32, + "is_custom_model": false, + "total_engaged_users": 6, + "total_chat_copy_events": 9, + "total_chat_insertion_events": 6 + } + ], + "total_engaged_users": 6 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 42, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 1, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 7 + }, + "total_active_users": 24, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 20, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 15, + "total_code_acceptances": 114, + "total_code_suggestions": 594, + "total_code_lines_accepted": 191, + "total_code_lines_suggested": 1425 + }, + { + "name": "go", + "total_engaged_users": 4, + "total_code_acceptances": 39, + "total_code_suggestions": 189, + "total_code_lines_accepted": 47, + "total_code_lines_suggested": 424 + }, + { + "name": "xml", + "total_engaged_users": 1, + "total_code_acceptances": 1, + "total_code_suggestions": 8, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 18 + }, + { + "name": "json", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "unknown", + "total_engaged_users": 1, + "total_code_acceptances": 3, + "total_code_suggestions": 79, + "total_code_lines_accepted": 3, + "total_code_lines_suggested": 179 + }, + { + "name": "sql", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + } + ], + "is_custom_model": false, + "total_engaged_users": 19 + } + ], + "total_engaged_users": 19 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "rust", + "total_engaged_users": 1, + "total_code_acceptances": 34, + "total_code_suggestions": 139, + "total_code_lines_accepted": 38, + "total_code_lines_suggested": 472 + }, + { + "name": "unknown", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + } + ], + "is_custom_model": false, + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + } + ], + "languages": [ + { + "name": "java", + "total_engaged_users": 15 + }, + { + "name": "go", + "total_engaged_users": 4 + }, + { + "name": "xml", + "total_engaged_users": 1 + }, + { + "name": "json", + "total_engaged_users": 0 + }, + { + "name": "unknown", + "total_engaged_users": 1 + }, + { + "name": "sql", + "total_engaged_users": 0 + }, + { + "name": "rust", + "total_engaged_users": 1 + } + ], + "total_engaged_users": 19 + } + }, + { + "date": "2024-11-23", + "copilot_ide_chat": { + "total_engaged_users": 0 + }, + "total_active_users": 1, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 1, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 1, + "total_code_acceptances": 19, + "total_code_suggestions": 59, + "total_code_lines_accepted": 38, + "total_code_lines_suggested": 183 + }, + { + "name": "xml", + "total_engaged_users": 1, + "total_code_acceptances": 2, + "total_code_suggestions": 2, + "total_code_lines_accepted": 2, + "total_code_lines_suggested": 5 + } + ], + "is_custom_model": false, + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + } + ], + "languages": [ + { + "name": "java", + "total_engaged_users": 1 + }, + { + "name": "xml", + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + } + }, + { + "date": "2024-11-24", + "copilot_ide_chat": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "total_chats": 12, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 4, + "total_chat_insertion_events": 3 + } + ], + "total_engaged_users": 1 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "total_chats": 3, + "is_custom_model": false, + "total_engaged_users": 1, + "total_chat_copy_events": 0, + "total_chat_insertion_events": 0 + } + ], + "total_engaged_users": 1 + } + ], + "total_engaged_users": 2 + }, + "total_active_users": 7, + "copilot_dotcom_chat": { + "total_engaged_users": 0 + }, + "total_engaged_users": 7, + "copilot_dotcom_pull_requests": { + "total_engaged_users": 0 + }, + "copilot_ide_code_completions": { + "editors": [ + { + "name": "JetBrains", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 6, + "total_code_acceptances": 52, + "total_code_suggestions": 279, + "total_code_lines_accepted": 113, + "total_code_lines_suggested": 776 + }, + { + "name": "xml", + "total_engaged_users": 2, + "total_code_acceptances": 9, + "total_code_suggestions": 23, + "total_code_lines_accepted": 9, + "total_code_lines_suggested": 61 + }, + { + "name": "sql", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 1 + }, + { + "name": "yaml", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 2, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 4 + } + ], + "is_custom_model": false, + "total_engaged_users": 6 + } + ], + "total_engaged_users": 6 + }, + { + "name": "vscode", + "models": [ + { + "name": "default", + "languages": [ + { + "name": "java", + "total_engaged_users": 1, + "total_code_acceptances": 1, + "total_code_suggestions": 1, + "total_code_lines_accepted": 1, + "total_code_lines_suggested": 1 + }, + { + "name": "xml", + "total_engaged_users": 0, + "total_code_acceptances": 0, + "total_code_suggestions": 1, + "total_code_lines_accepted": 0, + "total_code_lines_suggested": 10 + } + ], + "is_custom_model": false, + "total_engaged_users": 1 + } + ], + "total_engaged_users": 1 + } + ], + "languages": [ + { + "name": "java", + "total_engaged_users": 7 + }, + { + "name": "xml", + "total_engaged_users": 2 + }, + { + "name": "sql", + "total_engaged_users": 0 + }, + { + "name": "yaml", + "total_engaged_users": 0 + } + ], + "total_engaged_users": 7 + } + } +] \ No newline at end of file diff --git a/mock-data/organization_response_sample_seats.json b/mock-data/organization_seats_response_sample.json similarity index 100% rename from mock-data/organization_response_sample_seats.json rename to mock-data/organization_seats_response_sample.json diff --git a/mock-data/organization_response_sample.json b/mock-data/organization_usage_response_sample.json similarity index 100% rename from mock-data/organization_response_sample.json rename to mock-data/organization_usage_response_sample.json diff --git a/playwright.docker.config.ts b/playwright.docker.config.ts index 34ff5e2..7fedd51 100644 --- a/playwright.docker.config.ts +++ b/playwright.docker.config.ts @@ -3,6 +3,7 @@ import baseConfig from './playwright.config'; export default defineConfig({ ...baseConfig, + timeout: 5 * 1000, reporter: [ ['list'], ['html', { open: 'never', outputFolder: '/test-results/html' }], diff --git a/src/api/ExtractSeats.ts b/src/api/ExtractSeats.ts index 692ef84..00eff1a 100644 --- a/src/api/ExtractSeats.ts +++ b/src/api/ExtractSeats.ts @@ -3,8 +3,8 @@ import axios from "axios"; import { Seat } from "../model/Seat"; import config from '../config'; -import organizationMockedResponse_seats from '../../mock-data/organization_response_sample_seats.json'; -import enterpriseMockedResponse_seats from '../../mock-data/enterprise_response_sample_seats.json'; +import organizationMockedResponse_seats from '../../mock-data/organization_seats_response_sample.json'; +import enterpriseMockedResponse_seats from '../../mock-data/enterprise_seats_response_sample.json'; const headers = { Accept: "application/vnd.github+json", diff --git a/src/api/GitHubApi.ts b/src/api/GitHubApi.ts index 125c663..a22af23 100644 --- a/src/api/GitHubApi.ts +++ b/src/api/GitHubApi.ts @@ -1,14 +1,9 @@ -//Make a call to the GitHub API to get Copilot Metrics, the API is /api/github/orgs/toussaintt/copilot/usage -//Add the header Accept: application/vnd.github+json to the request -//Add also the Authorization: Bearer header where is hardcoded for now -//Also add X-GitHub-Api-Version: 2022-11-28 header -//Return the response from the API - import axios from "axios"; - import { Metrics } from "../model/Metrics"; -import organizationMockedResponse from '../../mock-data/organization_response_sample.json'; -import enterpriseMockedResponse from '../../mock-data/enterprise_response_sample.json'; +import { CopilotMetrics } from '../model/Copilot_Metrics'; +import { convertToMetrics } from './MetricsToUsageConverter'; +import organizationMockedMetricsResponse from '../../mock-data/organization_metrics_response_sample.json'; +import enterpriseMockedMetricsResponse from '../../mock-data/enterprise_metrics_response_sample.json'; import config from '../config'; const headers = { @@ -17,27 +12,43 @@ const headers = { ...(config.github.token ? { Authorization: `token ${config.github.token}` } : {}) }; -export const getMetricsApi = async (): Promise => { +const ensureCopilotMetrics = (data: any[]): CopilotMetrics[] => { + return data.map(item => { + if (!item.copilot_ide_code_completions) { + item.copilot_ide_code_completions = { editors: [] }; + } + item.copilot_ide_code_completions.editors?.forEach((editor: any) => { + editor.models?.forEach((model: any) => { + if (!model.languages) { + model.languages = []; + } + }); + }); + return item as CopilotMetrics; + }); +}; +export const getMetricsApi = async (): Promise<{ metrics: Metrics[], original: CopilotMetrics[] }> => { let response; - let metricsData; + let metricsData: Metrics[]; + let originalData: CopilotMetrics[]; if (config.mockedData) { console.log("Using mock data. Check VUE_APP_MOCKED_DATA variable."); - response = config.scope.type === "organization" ? organizationMockedResponse : enterpriseMockedResponse; - metricsData = response.map((item: any) => new Metrics(item)); + response = config.scope.type === "organization" ? organizationMockedMetricsResponse : enterpriseMockedMetricsResponse; + originalData = ensureCopilotMetrics(response); + metricsData = convertToMetrics(originalData); } else { response = await axios.get( - `${config.github.apiUrl}/copilot/usage`, + `${config.github.apiUrl}/copilot/metrics`, { - headers + headers } ); - - - metricsData = response.data.map((item: any) => new Metrics(item)); + originalData = ensureCopilotMetrics(response.data); + metricsData = convertToMetrics(originalData); } - return metricsData; + return { metrics: metricsData, original: originalData }; }; export const getTeams = async (): Promise => { @@ -48,12 +59,12 @@ export const getTeams = async (): Promise => { return response.data; } -export const getTeamMetricsApi = async (): Promise => { +export const getTeamMetricsApi = async (): Promise<{ metrics: Metrics[], original: CopilotMetrics[] }> => { console.log("config.github.team: " + config.github.team); if (config.github.team && config.github.team.trim() !== '') { const response = await axios.get( - `${config.github.apiUrl}/team/${config.github.team}/copilot/usage`, + `${config.github.apiUrl}/team/${config.github.team}/copilot/metrics`, { headers: { Accept: "application/vnd.github+json", @@ -63,9 +74,10 @@ export const getTeamMetricsApi = async (): Promise => { } ); - return response.data.map((item: any) => new Metrics(item)); + const originalData = ensureCopilotMetrics(response.data); + const metricsData = convertToMetrics(originalData); + return { metrics: metricsData, original: originalData }; } - return []; - + return { metrics: [], original: [] }; } \ No newline at end of file diff --git a/src/api/MetricsToUsageConverter.ts b/src/api/MetricsToUsageConverter.ts new file mode 100644 index 0000000..a9a6d0f --- /dev/null +++ b/src/api/MetricsToUsageConverter.ts @@ -0,0 +1,55 @@ +import { Metrics, BreakdownData } from "../model/Metrics"; +import { CopilotMetrics } from '../model/Copilot_Metrics'; + +export const convertToMetrics = (copilotMetrics: CopilotMetrics[]): Metrics[] => { + try { + const usageData: Metrics[] = copilotMetrics.map(metric => { + const breakdown: BreakdownData[] = []; + + metric.copilot_ide_code_completions?.editors?.forEach(editor => { + editor.models?.forEach(model => { + model.languages?.forEach(language => { + breakdown.push(new BreakdownData({ + language: language.name, + editor: editor.name, + suggestions_count: language.total_code_suggestions, + acceptances_count: language.total_code_acceptances, + lines_suggested: language.total_code_lines_suggested, + lines_accepted: language.total_code_lines_accepted, + active_users: language.total_engaged_users + })); + }); + }); + }); + + const totalChatInsertions = metric.copilot_ide_chat?.editors?.reduce((sum, editor) => + sum + editor.models?.reduce((sum, model) => sum + model.total_chat_insertion_events, 0), 0) || 0; + + const totalChatCopies = metric.copilot_ide_chat?.editors?.reduce((sum, editor) => + sum + editor.models?.reduce((sum, model) => sum + model.total_chat_copy_events, 0), 0) || 0; + + console.log(`Date: ${metric.date}`); + console.log(`Total Chat Insertions: ${totalChatInsertions}`); + console.log(`Total Chat Copies: ${totalChatCopies}`); + + return new Metrics({ + day: metric.date, + total_suggestions_count: breakdown.reduce((sum, item) => sum + item.suggestions_count, 0), + total_acceptances_count: breakdown.reduce((sum, item) => sum + item.acceptances_count, 0), + total_lines_suggested: breakdown.reduce((sum, item) => sum + item.lines_suggested, 0), + total_lines_accepted: breakdown.reduce((sum, item) => sum + item.lines_accepted, 0), + total_active_users: metric.total_active_users || 0, + total_chat_acceptances: totalChatInsertions + totalChatCopies, + total_chat_turns: metric.copilot_ide_chat?.editors?.reduce((sum, editor) => + sum + editor.models?.reduce((sum, model) => sum + model.total_chats, 0), 0) || 0, + total_active_chat_users: metric.copilot_ide_chat?.total_engaged_users || 0, + breakdown: breakdown + }); + }); + + return usageData; + } catch (error) { + console.error('Error converting metrics to usage format:', error); + return []; + } +}; \ No newline at end of file diff --git a/src/api/MetricsValidator.ts b/src/api/MetricsValidator.ts new file mode 100644 index 0000000..39f5b0e --- /dev/null +++ b/src/api/MetricsValidator.ts @@ -0,0 +1,94 @@ +import { CopilotMetrics } from '../model/Copilot_Metrics'; + +export class MetricsValidator { + metrics: CopilotMetrics[]; + + constructor(metrics: CopilotMetrics[]) { + this.metrics = metrics; + } + + checkContinuousDates(): string[] { + const dates = this.metrics.map(metric => new Date(metric.date)); + dates.sort((a, b) => a.getTime() - b.getTime()); + + const missingDates: string[] = []; + for (let i = 1; i < dates.length; i++) { + const prevDate = dates[i - 1]; + const currDate = dates[i]; + const diffDays = (currDate.getTime() - prevDate.getTime()) / (1000 * 60 * 60 * 24); + + if (diffDays > 1) { + for (let d = 1; d < diffDays; d++) { + const missingDate = new Date(prevDate.getTime() + d * (1000 * 60 * 60 * 24)); + missingDates.push(missingDate.toISOString().split('T')[0]); + } + } + } + return missingDates; + } + + validateCodeCompletions(): { date: string, editor: string, language: string }[] { + const invalidEntries: { date: string, editor: string, language: string }[] = []; + + this.metrics.forEach(metric => { + if (metric.copilot_ide_code_completions?.editors) { + metric.copilot_ide_code_completions.editors.forEach(editor => { + if (editor.models) { + editor.models.forEach(model => { + if (model.languages) { + model.languages.forEach(language => { + if (language.total_code_acceptances > language.total_code_suggestions || + language.total_code_lines_accepted > language.total_code_lines_suggested) { + invalidEntries.push({ + date: metric.date, + editor: editor.name, + language: language.name + }); + } + }); + } + }); + } + }); + } + }); + + return invalidEntries; + } + + validateChatEngagedUsers(): { date: string, editor: string, total_engaged_users: number }[] { + const invalidEntries: { date: string, editor: string, total_engaged_users: number }[] = []; + + this.metrics.forEach(metric => { + if (metric.copilot_ide_chat?.editors) { + metric.copilot_ide_chat.editors.forEach(editor => { + if (editor.models) { + const totalModelEngagedUsers = editor.models.reduce((sum, model) => + sum + (model.total_engaged_users || 0), 0); + if (totalModelEngagedUsers < (editor.total_engaged_users || 0)) { + invalidEntries.push({ + date: metric.date, + editor: editor.name, + total_engaged_users: editor.total_engaged_users + }); + } + } + }); + } + }); + + return invalidEntries; + } + + checkAllMetrics() { + const nonContinuousDates = this.checkContinuousDates(); + const invalidCodeCompletions = this.validateCodeCompletions(); + const invalidChatEngagedUsers = this.validateChatEngagedUsers(); + + return { + nonContinuousDates, + invalidCodeCompletions, + invalidChatEngagedUsers + }; + } +} \ No newline at end of file diff --git a/src/components/ApiResponse.vue b/src/components/ApiResponse.vue index c9fa568..cfae94c 100644 --- a/src/components/ApiResponse.vue +++ b/src/components/ApiResponse.vue @@ -1,91 +1,132 @@ diff --git a/src/components/BreakdownComponent.vue b/src/components/BreakdownComponent.vue index eb9da17..4bb7b11 100644 --- a/src/components/BreakdownComponent.vue +++ b/src/components/BreakdownComponent.vue @@ -19,11 +19,11 @@ - +
-
Top 5 {{ breakdownDisplayNamePlural }} by accepted prompts
+
Top 5 {{ breakdownDisplayNamePlural }} by accepted suggestions (prompts)
@@ -31,13 +31,25 @@
- +
-
Top 5 {{ breakdownDisplayNamePlural }} by acceptance rate
+
Acceptance Rate (by count) for Top 5 {{ breakdownDisplayNamePlural }}
- + +
+
+
+
+ + + + +
+
Acceptance Rate (by code lines) for Top 5 {{ breakdownDisplayNamePlural }}
+
+
@@ -53,8 +65,11 @@ {{ item.name }} {{ item.acceptedPrompts }} + {{ item.suggestedPrompts }} {{ item.acceptedLinesOfCode }} - {{ item.acceptanceRate.toFixed(2) }}% + {{ item.suggestedLinesOfCode }} + {{ item.acceptanceRateByCount.toFixed(2) }}% + {{ item.acceptanceRateByLines.toFixed(2) }}% @@ -74,9 +89,9 @@ import { ArcElement, CategoryScale, LinearScale, + BarElement, PointElement, LineElement, - BarElement, Title, Tooltip, Legend @@ -120,8 +135,11 @@ export default defineComponent({ return [ { title: `${this.breakdownDisplayName} Name`, key: 'name' }, { title: 'Accepted Prompts', key: 'acceptedPrompts' }, + { title: 'Suggested Prompts', key: 'suggestedPrompts' }, { title: 'Accepted Lines of Code', key: 'acceptedLinesOfCode' }, - { title: 'Acceptance Rate (%)', key: 'acceptanceRate' }, + { title: 'Suggested Lines of Code', key: 'suggestedLinesOfCode' }, + { title: 'Acceptance Rate by Count (%)', key: 'acceptanceRateByCount' }, + { title: 'Acceptance Rate by Lines (%)', key: 'acceptanceRateByLines' }, ]; }, }, @@ -139,8 +157,11 @@ export default defineComponent({ //Top 5 by accepted prompts let breakdownsChartDataTop5AcceptedPrompts = ref<{ labels: string[]; datasets: any[] }>({ labels: [], datasets: [] }); - //Top 5 by acceptance rate - let breakdownsChartDataTop5AcceptanceRate = ref<{ labels: string[]; datasets: any[] }>({ labels: [], datasets: [] }); + //Acceptance Rate by lines for top 5 by accepted prompts + let breakdownsChartDataTop5AcceptedPromptsByLines = ref<{ labels: string[]; datasets: any[] }>({ labels: [], datasets: [] }); + + //Acceptance Rate by counts for top 5 by accepted prompts + let breakdownsChartDataTop5AcceptedPromptsByCounts = ref<{ labels: string[]; datasets: any[] }>({ labels: [], datasets: [] }); const chartOptions = { responsive: true, @@ -148,15 +169,19 @@ export default defineComponent({ }; const pieChartColors = ref([ - '#4B0082', '#41B883', '#483D8B', '#87CEFA', - '#32CD32' - ]); + '#4B0082', // Indigo + '#41B883', // Vue Green + '#6495ED', // Cornflower Blue + '#87CEFA', // Light Sky Blue + '#7CFC00' // Lawn Green +]); const data = toRef(props, 'metrics').value; // Process the breakdown separately data.forEach((m: Metrics) => m.breakdown.forEach(breakdownData => { + //console.log('Processing breakdown data:', breakdownData); const breakdownName = breakdownData[props.breakdownKey as keyof typeof breakdownData] as string; let breakdown = breakdownList.value.find(b => b.name === breakdownName); @@ -165,6 +190,7 @@ export default defineComponent({ breakdown = new Breakdown({ name: breakdownName, acceptedPrompts: breakdownData.acceptances_count, + suggestedPrompts: breakdownData.suggestions_count, suggestedLinesOfCode: breakdownData.lines_suggested, acceptedLinesOfCode: breakdownData.lines_accepted, }); @@ -172,40 +198,49 @@ export default defineComponent({ } else { // Update the existing breakdown object breakdown.acceptedPrompts += breakdownData.acceptances_count; + breakdown.suggestedPrompts += breakdownData.suggestions_count; breakdown.suggestedLinesOfCode += breakdownData.lines_suggested; breakdown.acceptedLinesOfCode += breakdownData.lines_accepted; } - // Recalculate the acceptance rate - breakdown.acceptanceRate = breakdown.suggestedLinesOfCode !== 0 ? (breakdown.acceptedLinesOfCode / breakdown.suggestedLinesOfCode) * 100 : 0; - })); + // Recalculate the acceptance rates + breakdown.acceptanceRateByCount = breakdown.suggestedPrompts !== 0 ? (breakdown.acceptedPrompts / breakdown.suggestedPrompts) * 100 : 0; + breakdown.acceptanceRateByLines = breakdown.suggestedLinesOfCode !== 0 ? (breakdown.acceptedLinesOfCode / breakdown.suggestedLinesOfCode) * 100 : 0; - //Sort breakdowns map by acceptance rate - breakdownList.value.sort((a, b) => b.acceptanceRate - a.acceptanceRate); + // Log each breakdown for debugging + // console.log('Breakdown:', breakdown); + })); - // Get the top 5 breakdowns by acceptance rate - const top5BreakdownsAcceptanceRate = breakdownList.value.slice(0, 5); + //Sort breakdowns map by accepted prompts + breakdownList.value.sort((a, b) => b.acceptedPrompts - a.acceptedPrompts); - breakdownsChartDataTop5AcceptanceRate.value = { - labels: top5BreakdownsAcceptanceRate.map(breakdown => breakdown.name), + // Get the top 5 breakdowns by accepted prompts + const top5BreakdownsAcceptedPrompts = breakdownList.value.slice(0, 5); + + breakdownsChartDataTop5AcceptedPrompts.value = { + labels: top5BreakdownsAcceptedPrompts.map(breakdown => breakdown.name), datasets: [ { - data: top5BreakdownsAcceptanceRate.map(breakdown => breakdown.acceptanceRate.toFixed(2)), + data: top5BreakdownsAcceptedPrompts.map(breakdown => breakdown.acceptedPrompts), backgroundColor: pieChartColors.value, }, ], }; - //Sort breakdowns map by accepted prompts - breakdownList.value.sort((a, b) => b.acceptedPrompts - a.acceptedPrompts); + breakdownsChartDataTop5AcceptedPromptsByLines.value = { + labels: top5BreakdownsAcceptedPrompts.map(breakdown => breakdown.name), + datasets: [ + { + data: top5BreakdownsAcceptedPrompts.map(breakdown => breakdown.acceptanceRateByLines.toFixed(2)), + backgroundColor: pieChartColors.value, + }, + ], + }; - // Get the top 5 breakdowns by accepted prompts - const top5BreakdownsAcceptedPrompts = breakdownList.value.slice(0, 5); - - breakdownsChartDataTop5AcceptedPrompts.value = { + breakdownsChartDataTop5AcceptedPromptsByCounts.value = { labels: top5BreakdownsAcceptedPrompts.map(breakdown => breakdown.name), datasets: [ { - data: top5BreakdownsAcceptedPrompts.map(breakdown => breakdown.acceptedPrompts), + data: top5BreakdownsAcceptedPrompts.map(breakdown => breakdown.acceptanceRateByCount.toFixed(2)), backgroundColor: pieChartColors.value, }, ], @@ -214,7 +249,7 @@ export default defineComponent({ numberOfBreakdowns.value = breakdownList.value.length; return { chartOptions, breakdownList, numberOfBreakdowns, - breakdownsChartData, breakdownsChartDataTop5AcceptedPrompts, breakdownsChartDataTop5AcceptanceRate }; + breakdownsChartData, breakdownsChartDataTop5AcceptedPrompts, breakdownsChartDataTop5AcceptedPromptsByLines, breakdownsChartDataTop5AcceptedPromptsByCounts }; }, diff --git a/src/components/MainComponent.vue b/src/components/MainComponent.vue index d142002..166f22b 100644 --- a/src/components/MainComponent.vue +++ b/src/components/MainComponent.vue @@ -5,9 +5,7 @@ mdi-github - Copilot Metrics Viewer | {{ capitalizedItemName }} : {{ displayedViewName }} {{ teamName }} - - + Copilot Metrics Viewer | {{ capitalizedItemName }} : {{ displayedViewName }} {{ teamName }}

{{ mockedDataMessage }}

@@ -15,15 +13,12 @@ Logout - @@ -44,24 +39,23 @@ - + -