Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/extension/conversation/vscode-node/feedbackCollection.ts
13399 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as vscode from 'vscode';
7
import { ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService';
8
import { TextDocumentSnapshot } from '../../../platform/editing/common/textDocumentSnapshot';
9
import { ILogService } from '../../../platform/log/common/logService';
10
import { IReviewService } from '../../../platform/review/common/reviewService';
11
import { CancellationToken } from '../../../util/vs/base/common/cancellation';
12
import { DisposableStore } from '../../../util/vs/base/common/lifecycle';
13
import * as path from '../../../util/vs/base/common/path';
14
import { IInstantiationService, ServicesAccessor } from '../../../util/vs/platform/instantiation/common/instantiation';
15
import { FeedbackGenerator } from '../../prompt/node/feedbackGenerator';
16
import { CurrentChange } from '../../prompts/node/feedback/currentChange';
17
18
const maxRequests = 10;
19
const maxRequestsInterval = 5 * 60 * 1000;
20
const requestDelay = 10 * 1000;
21
let requestTimes: number[] = [];
22
23
export function startFeedbackCollection(accessor: ServicesAccessor) {
24
const configurationService = accessor.get(IConfigurationService);
25
const reviewService = accessor.get(IReviewService);
26
const instantiationService = accessor.get(IInstantiationService);
27
const logService = accessor.get(ILogService);
28
const disposables = new DisposableStore();
29
const enabled = configurationService.getConfig(ConfigKey.Advanced.FeedbackOnChange);
30
if (!enabled) {
31
return disposables;
32
}
33
const collection = reviewService.getDiagnosticCollection();
34
const feedbackGenerator = instantiationService.createInstance(FeedbackGenerator);
35
disposables.add(vscode.workspace.onDidChangeTextDocument(async event => {
36
if (event.document.uri.scheme === 'file' && event.contentChanges.length && event.document === vscode.window.activeTextEditor?.document) {
37
try {
38
logService.warn('Document changed, delaying diagnostics request');
39
const version = event.document.version;
40
await new Promise(resolve => setTimeout(resolve, requestDelay));
41
if (version !== event.document.version) {
42
logService.warn('Skipping diagnostics request because the document has changed');
43
return;
44
}
45
const now = Date.now();
46
const before = now - maxRequestsInterval;
47
requestTimes = requestTimes.filter(t => t > before);
48
if (requestTimes.length >= maxRequests) {
49
logService.warn('Max requests reached, skipping diagnostics request');
50
return;
51
}
52
requestTimes.push(now);
53
logService.trace('Requesting diagnostics');
54
55
const selection = vscode.window.activeTextEditor?.selection;
56
57
// TODO: Use all changes in the current document.
58
const change = await instantiationService.invokeFunction(CurrentChange.getCurrentChange, event.document, selection.start);
59
if (!change) {
60
logService.trace('No change found in the current document at the current position.');
61
return [];
62
}
63
64
const result = await feedbackGenerator.generateComments([
65
{
66
document: TextDocumentSnapshot.create(event.document),
67
relativeDocumentPath: path.basename(event.document.uri.fsPath),
68
change,
69
selection
70
}
71
], CancellationToken.None);
72
if (result.type === 'success') {
73
const diagnostics = result.comments.map(comment => new vscode.Diagnostic(comment.range, typeof comment.body === 'string' ? comment.body : comment.body.value, vscode.DiagnosticSeverity.Information));
74
collection.set(event.document.uri, diagnostics);
75
}
76
} catch (err) {
77
logService.error(err, 'Error generating diagnostics');
78
}
79
}
80
}));
81
disposables.add(vscode.workspace.onDidCloseTextDocument(doc => {
82
collection.set(doc.uri, undefined);
83
}));
84
return disposables;
85
}
86
87