@vscode/chat-lib 0.43.2026040702 → 0.43.2026040706-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/_internal/extension/common/constants.d.ts +2 -1
- package/dist/src/_internal/extension/common/constants.d.ts.map +1 -1
- package/dist/src/_internal/extension/common/constants.js +3 -0
- package/dist/src/_internal/extension/common/constants.js.map +1 -1
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/ghostText/completionsFromNetwork.d.ts +1 -5
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/ghostText/completionsFromNetwork.d.ts.map +1 -1
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/ghostText/completionsFromNetwork.js +3 -11
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/ghostText/completionsFromNetwork.js.map +1 -1
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/networking.d.ts +0 -30
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/networking.d.ts.map +1 -1
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/networking.js +4 -82
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/networking.js.map +1 -1
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/openai/fetch.d.ts +2 -10
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/openai/fetch.d.ts.map +1 -1
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/openai/fetch.js +26 -173
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/openai/fetch.js.map +1 -1
- package/dist/src/_internal/extension/inlineEdits/node/nextEditCache.d.ts +11 -0
- package/dist/src/_internal/extension/inlineEdits/node/nextEditCache.d.ts.map +1 -1
- package/dist/src/_internal/extension/inlineEdits/node/nextEditCache.js +21 -3
- package/dist/src/_internal/extension/inlineEdits/node/nextEditCache.js.map +1 -1
- package/dist/src/_internal/extension/inlineEdits/node/nextEditProvider.d.ts +2 -2
- package/dist/src/_internal/extension/inlineEdits/node/nextEditProvider.d.ts.map +1 -1
- package/dist/src/_internal/extension/inlineEdits/node/nextEditProvider.js +34 -12
- package/dist/src/_internal/extension/inlineEdits/node/nextEditProvider.js.map +1 -1
- package/dist/src/_internal/extension/prompt/node/chatMLFetcher.d.ts +1 -1
- package/dist/src/_internal/extension/prompt/node/chatMLFetcher.d.ts.map +1 -1
- package/dist/src/_internal/extension/prompt/node/chatMLFetcher.js +37 -24
- package/dist/src/_internal/extension/prompt/node/chatMLFetcher.js.map +1 -1
- package/dist/src/_internal/extension/prompt/node/chatMLFetcherTelemetry.d.ts.map +1 -1
- package/dist/src/_internal/extension/prompt/node/chatMLFetcherTelemetry.js +4 -2
- package/dist/src/_internal/extension/prompt/node/chatMLFetcherTelemetry.js.map +1 -1
- package/dist/src/_internal/extension/xtab/common/fetchStreamError.d.ts +10 -0
- package/dist/src/_internal/extension/xtab/common/fetchStreamError.d.ts.map +1 -0
- package/dist/src/_internal/extension/xtab/common/fetchStreamError.js +19 -0
- package/dist/src/_internal/extension/xtab/common/fetchStreamError.js.map +1 -0
- package/dist/src/_internal/extension/xtab/node/cursorLineDivergence.d.ts +44 -0
- package/dist/src/_internal/extension/xtab/node/cursorLineDivergence.d.ts.map +1 -0
- package/dist/src/_internal/extension/xtab/node/cursorLineDivergence.js +181 -0
- package/dist/src/_internal/extension/xtab/node/cursorLineDivergence.js.map +1 -0
- package/dist/src/_internal/extension/xtab/node/editIntent.d.ts +31 -0
- package/dist/src/_internal/extension/xtab/node/editIntent.d.ts.map +1 -0
- package/dist/src/_internal/extension/xtab/node/editIntent.js +193 -0
- package/dist/src/_internal/extension/xtab/node/editIntent.js.map +1 -0
- package/dist/src/_internal/extension/xtab/node/responseFormatHandlers.d.ts +52 -0
- package/dist/src/_internal/extension/xtab/node/responseFormatHandlers.d.ts.map +1 -0
- package/dist/src/_internal/extension/xtab/node/responseFormatHandlers.js +134 -0
- package/dist/src/_internal/extension/xtab/node/responseFormatHandlers.js.map +1 -0
- package/dist/src/_internal/extension/xtab/node/xtabCustomDiffPatchResponseHandler.d.ts +1 -1
- package/dist/src/_internal/extension/xtab/node/xtabCustomDiffPatchResponseHandler.d.ts.map +1 -1
- package/dist/src/_internal/extension/xtab/node/xtabCustomDiffPatchResponseHandler.js +5 -5
- package/dist/src/_internal/extension/xtab/node/xtabCustomDiffPatchResponseHandler.js.map +1 -1
- package/dist/src/_internal/extension/xtab/node/xtabProvider.d.ts +10 -37
- package/dist/src/_internal/extension/xtab/node/xtabProvider.d.ts.map +1 -1
- package/dist/src/_internal/extension/xtab/node/xtabProvider.js +315 -361
- package/dist/src/_internal/extension/xtab/node/xtabProvider.js.map +1 -1
- package/dist/src/_internal/extension/xtab/node/xtabUtils.d.ts +10 -0
- package/dist/src/_internal/extension/xtab/node/xtabUtils.d.ts.map +1 -1
- package/dist/src/_internal/extension/xtab/node/xtabUtils.js +24 -0
- package/dist/src/_internal/extension/xtab/node/xtabUtils.js.map +1 -1
- package/dist/src/_internal/platform/authentication/common/copilotToken.d.ts +1 -0
- package/dist/src/_internal/platform/authentication/common/copilotToken.d.ts.map +1 -1
- package/dist/src/_internal/platform/authentication/common/copilotToken.js +3 -0
- package/dist/src/_internal/platform/authentication/common/copilotToken.js.map +1 -1
- package/dist/src/_internal/platform/chat/common/chatMLFetcher.d.ts +1 -0
- package/dist/src/_internal/platform/chat/common/chatMLFetcher.d.ts.map +1 -1
- package/dist/src/_internal/platform/chat/common/chatMLFetcher.js +4 -0
- package/dist/src/_internal/platform/chat/common/chatMLFetcher.js.map +1 -1
- package/dist/src/_internal/platform/chat/common/commonTypes.d.ts.map +1 -1
- package/dist/src/_internal/platform/chat/common/commonTypes.js +34 -4
- package/dist/src/_internal/platform/chat/common/commonTypes.js.map +1 -1
- package/dist/src/_internal/platform/configuration/common/configurationService.d.ts +30 -13
- package/dist/src/_internal/platform/configuration/common/configurationService.d.ts.map +1 -1
- package/dist/src/_internal/platform/configuration/common/configurationService.js +37 -20
- package/dist/src/_internal/platform/configuration/common/configurationService.js.map +1 -1
- package/dist/src/_internal/platform/configuration/common/defaultsOnlyConfigurationService.d.ts +1 -1
- package/dist/src/_internal/platform/configuration/common/defaultsOnlyConfigurationService.d.ts.map +1 -1
- package/dist/src/_internal/platform/configuration/common/defaultsOnlyConfigurationService.js +1 -1
- package/dist/src/_internal/platform/configuration/common/defaultsOnlyConfigurationService.js.map +1 -1
- package/dist/src/_internal/platform/endpoint/common/chatModelCapabilities.d.ts +20 -0
- package/dist/src/_internal/platform/endpoint/common/chatModelCapabilities.d.ts.map +1 -1
- package/dist/src/_internal/platform/endpoint/common/chatModelCapabilities.js +49 -2
- package/dist/src/_internal/platform/endpoint/common/chatModelCapabilities.js.map +1 -1
- package/dist/src/_internal/platform/endpoint/common/endpointProvider.d.ts +2 -0
- package/dist/src/_internal/platform/endpoint/common/endpointProvider.d.ts.map +1 -1
- package/dist/src/_internal/platform/endpoint/common/endpointProvider.js.map +1 -1
- package/dist/src/_internal/platform/endpoint/common/statefulMarkerContainer.d.ts +5 -0
- package/dist/src/_internal/platform/endpoint/common/statefulMarkerContainer.d.ts.map +1 -1
- package/dist/src/_internal/platform/endpoint/common/statefulMarkerContainer.js +13 -0
- package/dist/src/_internal/platform/endpoint/common/statefulMarkerContainer.js.map +1 -1
- package/dist/src/_internal/platform/endpoint/node/chatEndpoint.d.ts +14 -2
- package/dist/src/_internal/platform/endpoint/node/chatEndpoint.d.ts.map +1 -1
- package/dist/src/_internal/platform/endpoint/node/chatEndpoint.js +41 -71
- package/dist/src/_internal/platform/endpoint/node/chatEndpoint.js.map +1 -1
- package/dist/src/_internal/platform/endpoint/node/imageLimits.d.ts +14 -0
- package/dist/src/_internal/platform/endpoint/node/imageLimits.d.ts.map +1 -0
- package/dist/src/_internal/platform/endpoint/node/imageLimits.js +156 -0
- package/dist/src/_internal/platform/endpoint/node/imageLimits.js.map +1 -0
- package/dist/src/_internal/platform/endpoint/node/messagesApi.d.ts +4 -12
- package/dist/src/_internal/platform/endpoint/node/messagesApi.d.ts.map +1 -1
- package/dist/src/_internal/platform/endpoint/node/messagesApi.js +39 -162
- package/dist/src/_internal/platform/endpoint/node/messagesApi.js.map +1 -1
- package/dist/src/_internal/platform/endpoint/node/responsesApi.d.ts +15 -2
- package/dist/src/_internal/platform/endpoint/node/responsesApi.d.ts.map +1 -1
- package/dist/src/_internal/platform/endpoint/node/responsesApi.js +259 -42
- package/dist/src/_internal/platform/endpoint/node/responsesApi.js.map +1 -1
- package/dist/src/_internal/platform/git/common/gitService.d.ts +8 -11
- package/dist/src/_internal/platform/git/common/gitService.d.ts.map +1 -1
- package/dist/src/_internal/platform/git/common/gitService.js.map +1 -1
- package/dist/src/_internal/platform/github/common/githubAPI.d.ts +1 -0
- package/dist/src/_internal/platform/github/common/githubAPI.d.ts.map +1 -1
- package/dist/src/_internal/platform/github/common/githubAPI.js +2 -0
- package/dist/src/_internal/platform/github/common/githubAPI.js.map +1 -1
- package/dist/src/_internal/platform/github/common/githubService.d.ts +3 -2
- package/dist/src/_internal/platform/github/common/githubService.d.ts.map +1 -1
- package/dist/src/_internal/platform/github/common/githubService.js.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/dataTypes/xtabPromptOptions.d.ts +15 -0
- package/dist/src/_internal/platform/inlineEdits/common/dataTypes/xtabPromptOptions.d.ts.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/dataTypes/xtabPromptOptions.js +18 -2
- package/dist/src/_internal/platform/inlineEdits/common/dataTypes/xtabPromptOptions.js.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/inlineEditLogContext.d.ts +12 -3
- package/dist/src/_internal/platform/inlineEdits/common/inlineEditLogContext.d.ts.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/inlineEditLogContext.js +72 -46
- package/dist/src/_internal/platform/inlineEdits/common/inlineEditLogContext.js.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/utils/utils.d.ts +3 -0
- package/dist/src/_internal/platform/inlineEdits/common/utils/utils.d.ts.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/utils/utils.js +12 -0
- package/dist/src/_internal/platform/inlineEdits/common/utils/utils.js.map +1 -1
- package/dist/src/_internal/platform/log/common/logService.d.ts +5 -0
- package/dist/src/_internal/platform/log/common/logService.d.ts.map +1 -1
- package/dist/src/_internal/platform/log/common/logService.js +22 -0
- package/dist/src/_internal/platform/log/common/logService.js.map +1 -1
- package/dist/src/_internal/platform/nesFetch/node/completionsFetchServiceImpl.d.ts +1 -1
- package/dist/src/_internal/platform/nesFetch/node/completionsFetchServiceImpl.d.ts.map +1 -1
- package/dist/src/_internal/platform/nesFetch/node/completionsFetchServiceImpl.js +1 -1
- package/dist/src/_internal/platform/nesFetch/node/completionsFetchServiceImpl.js.map +1 -1
- package/dist/src/_internal/platform/networking/common/anthropic.d.ts +0 -58
- package/dist/src/_internal/platform/networking/common/anthropic.d.ts.map +1 -1
- package/dist/src/_internal/platform/networking/common/anthropic.js +6 -67
- package/dist/src/_internal/platform/networking/common/anthropic.js.map +1 -1
- package/dist/src/_internal/platform/networking/common/fetch.d.ts +0 -12
- package/dist/src/_internal/platform/networking/common/fetch.d.ts.map +1 -1
- package/dist/src/_internal/platform/networking/common/fetch.js +5 -1
- package/dist/src/_internal/platform/networking/common/fetch.js.map +1 -1
- package/dist/src/_internal/platform/networking/common/fetcherService.d.ts +1 -0
- package/dist/src/_internal/platform/networking/common/fetcherService.d.ts.map +1 -1
- package/dist/src/_internal/platform/networking/common/fetcherService.js.map +1 -1
- package/dist/src/_internal/platform/networking/common/networking.d.ts +22 -4
- package/dist/src/_internal/platform/networking/common/networking.d.ts.map +1 -1
- package/dist/src/_internal/platform/networking/common/networking.js.map +1 -1
- package/dist/src/_internal/platform/networking/node/chatStream.d.ts +10 -0
- package/dist/src/_internal/platform/networking/node/chatStream.d.ts.map +1 -1
- package/dist/src/_internal/platform/networking/node/chatStream.js +28 -0
- package/dist/src/_internal/platform/networking/node/chatStream.js.map +1 -1
- package/dist/src/_internal/platform/networking/node/chatWebSocketManager.d.ts +24 -5
- package/dist/src/_internal/platform/networking/node/chatWebSocketManager.d.ts.map +1 -1
- package/dist/src/_internal/platform/networking/node/chatWebSocketManager.js +67 -20
- package/dist/src/_internal/platform/networking/node/chatWebSocketManager.js.map +1 -1
- package/dist/src/_internal/platform/networking/node/chatWebSocketTelemetry.d.ts +15 -1
- package/dist/src/_internal/platform/networking/node/chatWebSocketTelemetry.d.ts.map +1 -1
- package/dist/src/_internal/platform/networking/node/chatWebSocketTelemetry.js +51 -7
- package/dist/src/_internal/platform/networking/node/chatWebSocketTelemetry.js.map +1 -1
- package/dist/src/_internal/platform/otel/common/genAiEvents.d.ts.map +1 -1
- package/dist/src/_internal/platform/otel/common/genAiEvents.js +10 -2
- package/dist/src/_internal/platform/otel/common/genAiEvents.js.map +1 -1
- package/dist/src/_internal/platform/otel/common/index.d.ts +1 -1
- package/dist/src/_internal/platform/otel/common/index.d.ts.map +1 -1
- package/dist/src/_internal/platform/otel/common/index.js +2 -1
- package/dist/src/_internal/platform/otel/common/index.js.map +1 -1
- package/dist/src/_internal/platform/otel/common/messageFormatters.d.ts +13 -1
- package/dist/src/_internal/platform/otel/common/messageFormatters.d.ts.map +1 -1
- package/dist/src/_internal/platform/otel/common/messageFormatters.js +98 -0
- package/dist/src/_internal/platform/otel/common/messageFormatters.js.map +1 -1
- package/dist/src/_internal/platform/requestLogger/common/requestLogger.d.ts +170 -0
- package/dist/src/_internal/platform/requestLogger/common/requestLogger.d.ts.map +1 -0
- package/dist/src/_internal/platform/requestLogger/common/requestLogger.js +145 -0
- package/dist/src/_internal/platform/requestLogger/common/requestLogger.js.map +1 -0
- package/dist/src/_internal/platform/requestLogger/node/nullRequestLogger.d.ts +4 -4
- package/dist/src/_internal/platform/requestLogger/node/nullRequestLogger.d.ts.map +1 -1
- package/dist/src/_internal/platform/requestLogger/node/nullRequestLogger.js +1 -3
- package/dist/src/_internal/platform/requestLogger/node/nullRequestLogger.js.map +1 -1
- package/dist/src/_internal/platform/requestLogger/node/requestLogger.d.ts +4 -167
- package/dist/src/_internal/platform/requestLogger/node/requestLogger.d.ts.map +1 -1
- package/dist/src/_internal/platform/requestLogger/node/requestLogger.js +3 -139
- package/dist/src/_internal/platform/requestLogger/node/requestLogger.js.map +1 -1
- package/dist/src/main.d.ts +2 -0
- package/dist/src/main.d.ts.map +1 -1
- package/dist/src/main.js +48 -6
- package/dist/src/main.js.map +1 -1
- package/dist/src/package.json +192 -151
- package/package.json +70 -71
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/openai/stream.d.ts +0 -182
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/openai/stream.d.ts.map +0 -1
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/openai/stream.js +0 -558
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/openai/stream.js.map +0 -1
|
@@ -47,7 +47,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
47
47
|
};
|
|
48
48
|
var XtabProvider_1;
|
|
49
49
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
-
exports.
|
|
50
|
+
exports.XtabProvider = void 0;
|
|
51
51
|
exports.filterOutEditsWithSubstrings = filterOutEditsWithSubstrings;
|
|
52
52
|
exports.computeAreaAroundEditWindowLinesRange = computeAreaAroundEditWindowLinesRange;
|
|
53
53
|
exports.mapChatFetcherErrorToNoNextEditReason = mapChatFetcherErrorToNoNextEditReason;
|
|
@@ -55,8 +55,6 @@ exports.overrideModelConfig = overrideModelConfig;
|
|
|
55
55
|
exports.pickSystemPrompt = pickSystemPrompt;
|
|
56
56
|
exports.determineLanguageContextOptions = determineLanguageContextOptions;
|
|
57
57
|
exports.getPredictionContents = getPredictionContents;
|
|
58
|
-
exports.parseEditIntentFromStream = parseEditIntentFromStream;
|
|
59
|
-
exports.findMergeConflictMarkersRange = findMergeConflictMarkersRange;
|
|
60
58
|
const chatMLFetcher_1 = require("../../../platform/chat/common/chatMLFetcher");
|
|
61
59
|
const commonTypes_1 = require("../../../platform/chat/common/commonTypes");
|
|
62
60
|
const configurationService_1 = require("../../../platform/configuration/common/configurationService");
|
|
@@ -81,10 +79,12 @@ const nullExperimentationService_1 = require("../../../platform/telemetry/common
|
|
|
81
79
|
const workspaceService_1 = require("../../../platform/workspace/common/workspaceService");
|
|
82
80
|
const async_1 = require("../../../util/common/async");
|
|
83
81
|
const asyncIterableUtils_1 = require("../../../util/common/asyncIterableUtils");
|
|
82
|
+
const backwardCompatSetting_1 = require("../../../util/common/backwardCompatSetting");
|
|
84
83
|
const errors_1 = require("../../../util/common/errors");
|
|
85
84
|
const result_1 = require("../../../util/common/result");
|
|
86
85
|
const assert_1 = require("../../../util/vs/base/common/assert");
|
|
87
86
|
const async_2 = require("../../../util/vs/base/common/async");
|
|
87
|
+
const cancellation_1 = require("../../../util/vs/base/common/cancellation");
|
|
88
88
|
const path_1 = require("../../../util/vs/base/common/path");
|
|
89
89
|
const stopwatch_1 = require("../../../util/vs/base/common/stopwatch");
|
|
90
90
|
const uri_1 = require("../../../util/vs/base/common/uri");
|
|
@@ -95,11 +95,13 @@ const range_1 = require("../../../util/vs/editor/common/core/range");
|
|
|
95
95
|
const lineRange_1 = require("../../../util/vs/editor/common/core/ranges/lineRange");
|
|
96
96
|
const offsetRange_1 = require("../../../util/vs/editor/common/core/ranges/offsetRange");
|
|
97
97
|
const abstractText_1 = require("../../../util/vs/editor/common/core/text/abstractText");
|
|
98
|
+
const positionToOffset_1 = require("../../../util/vs/editor/common/core/text/positionToOffset");
|
|
98
99
|
const instantiation_1 = require("../../../util/vs/platform/instantiation/common/instantiation");
|
|
99
100
|
const vscodeTypesShim_1 = require("../../../util/common/test/shims/vscodeTypesShim");
|
|
100
101
|
const nearbyCursorInlineEditProvider_1 = require("../../inlineEdits/common/nearbyCursorInlineEditProvider");
|
|
101
102
|
const userInteractionMonitor_1 = require("../../inlineEdits/common/userInteractionMonitor");
|
|
102
103
|
const importFiltering_1 = require("../../inlineEdits/node/importFiltering");
|
|
104
|
+
const fetchStreamError_1 = require("../common/fetchStreamError");
|
|
103
105
|
const inlineSuggestion_1 = require("../common/inlineSuggestion");
|
|
104
106
|
const lintErrors_1 = require("../common/lintErrors");
|
|
105
107
|
const promptCrafting_1 = require("../common/promptCrafting");
|
|
@@ -109,6 +111,9 @@ const systemMessages_1 = require("../common/systemMessages");
|
|
|
109
111
|
const tags_1 = require("../common/tags");
|
|
110
112
|
const terminalOutput_1 = require("../common/terminalOutput");
|
|
111
113
|
const xtabCurrentDocument_1 = require("../common/xtabCurrentDocument");
|
|
114
|
+
const cursorLineDivergence_1 = require("./cursorLineDivergence");
|
|
115
|
+
const editIntent_1 = require("./editIntent");
|
|
116
|
+
const responseFormatHandlers_1 = require("./responseFormatHandlers");
|
|
112
117
|
const xtabCustomDiffPatchResponseHandler_1 = require("./xtabCustomDiffPatchResponseHandler");
|
|
113
118
|
const xtabEndpoint_1 = require("./xtabEndpoint");
|
|
114
119
|
const xtabNextCursorPredictor_1 = require("./xtabNextCursorPredictor");
|
|
@@ -134,6 +139,27 @@ var RetryState;
|
|
|
134
139
|
}
|
|
135
140
|
RetryState.Retrying = Retrying;
|
|
136
141
|
})(RetryState || (RetryState = {}));
|
|
142
|
+
var FetchResult;
|
|
143
|
+
(function (FetchResult) {
|
|
144
|
+
class Lines {
|
|
145
|
+
constructor(linesStream, getResponseSoFar, fetchRequestStopWatch) {
|
|
146
|
+
this.linesStream = linesStream;
|
|
147
|
+
this.getResponseSoFar = getResponseSoFar;
|
|
148
|
+
this.fetchRequestStopWatch = fetchRequestStopWatch;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
FetchResult.Lines = Lines;
|
|
152
|
+
class ModelNotFound {
|
|
153
|
+
static { this.INSTANCE = new ModelNotFound(); }
|
|
154
|
+
}
|
|
155
|
+
FetchResult.ModelNotFound = ModelNotFound;
|
|
156
|
+
class FetchFailure {
|
|
157
|
+
constructor(reason) {
|
|
158
|
+
this.reason = reason;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
FetchResult.FetchFailure = FetchFailure;
|
|
162
|
+
})(FetchResult || (FetchResult = {}));
|
|
137
163
|
let XtabProvider = class XtabProvider {
|
|
138
164
|
static { XtabProvider_1 = this; }
|
|
139
165
|
static { this.ID = configurationService_1.XTabProviderId; }
|
|
@@ -174,7 +200,8 @@ let XtabProvider = class XtabProvider {
|
|
|
174
200
|
return new statelessNextEditProvider_1.WithStatelessProviderTelemetry(noSuggestionReason, telemetry.build(result_1.Result.error(noSuggestionReason)));
|
|
175
201
|
}
|
|
176
202
|
const delaySession = this.userInteractionMonitor.createDelaySession(request.providerRequestStartDateTime);
|
|
177
|
-
const
|
|
203
|
+
const tracing = { tracer: logger, logContext, telemetry };
|
|
204
|
+
const iterator = this.doGetNextEdit(request, delaySession, tracing, cancellationToken, RetryState.NotRetrying.INSTANCE);
|
|
178
205
|
let res = await iterator.next(); // for-async-await loop doesn't work because we need to access the final return value
|
|
179
206
|
while (!res.done) {
|
|
180
207
|
yield new statelessNextEditProvider_1.WithStatelessProviderTelemetry(res.value, telemetry.build(result_1.Result.ok(undefined)));
|
|
@@ -195,29 +222,30 @@ let XtabProvider = class XtabProvider {
|
|
|
195
222
|
logContext.setProviderEndTime();
|
|
196
223
|
}
|
|
197
224
|
}
|
|
198
|
-
doGetNextEdit(request, delaySession,
|
|
199
|
-
return this.doGetNextEditWithSelection(request, (0, nearbyCursorInlineEditProvider_1.getOrDeduceSelectionFromLastEdit)(request.getActiveDocument()), delaySession,
|
|
225
|
+
doGetNextEdit(request, delaySession, tracing, cancellationToken, retryState) {
|
|
226
|
+
return this.doGetNextEditWithSelection(request, (0, nearbyCursorInlineEditProvider_1.getOrDeduceSelectionFromLastEdit)(request.getActiveDocument()), delaySession, tracing, cancellationToken, retryState);
|
|
200
227
|
}
|
|
201
|
-
async *doGetNextEditWithSelection(request, selection, delaySession,
|
|
228
|
+
async *doGetNextEditWithSelection(request, selection, delaySession, tracing, cancellationToken, retryState,
|
|
202
229
|
/**
|
|
203
230
|
* For cursor jump scenarios, this is the edit window around the original cursor position
|
|
204
231
|
* (before the jump). When provided, yielded edits will include this as `originalWindow`
|
|
205
232
|
* so the cache can serve the edit when the cursor is in either location.
|
|
206
233
|
*/
|
|
207
234
|
originalEditWindow) {
|
|
208
|
-
const tracer =
|
|
235
|
+
const tracer = tracing.tracer.createSubLogger(['XtabProvider', 'doGetNextEditWithSelection']);
|
|
236
|
+
const { logContext, telemetry } = tracing;
|
|
209
237
|
const activeDocument = request.getActiveDocument();
|
|
210
238
|
if (selection === null) {
|
|
211
239
|
return new statelessNextEditProvider_1.NoNextEditReason.Uncategorized(new Error('NoSelection'));
|
|
212
240
|
}
|
|
213
241
|
const { promptOptions, modelServiceConfig } = this.determineModelConfiguration(activeDocument);
|
|
214
|
-
|
|
215
|
-
const endpoint = this.getEndpointWithLogging(promptOptions.modelName, logContext,
|
|
242
|
+
telemetry.setModelConfig(JSON.stringify(modelServiceConfig));
|
|
243
|
+
const endpoint = this.getEndpointWithLogging(promptOptions.modelName, logContext, telemetry);
|
|
216
244
|
const cursorPosition = new position_1.Position(selection.endLineNumber, selection.endColumn);
|
|
217
245
|
const currentDocument = new xtabCurrentDocument_1.CurrentDocument(activeDocument.documentAfterEdits, cursorPosition);
|
|
218
|
-
this._configureDebounceTimings(request, currentDocument, promptOptions,
|
|
246
|
+
this._configureDebounceTimings(request, currentDocument, promptOptions, telemetry, delaySession, tracer);
|
|
219
247
|
const areaAroundEditWindowLinesRange = computeAreaAroundEditWindowLinesRange(currentDocument);
|
|
220
|
-
const editWindowLinesRange = this.computeEditWindowLinesRange(currentDocument, request, tracer,
|
|
248
|
+
const editWindowLinesRange = this.computeEditWindowLinesRange(currentDocument, request, tracer, telemetry);
|
|
221
249
|
const cursorOriginalLinesOffset = Math.max(0, currentDocument.cursorLineOffset - editWindowLinesRange.start);
|
|
222
250
|
const editWindowLastLineLength = currentDocument.transformer.getLineLength(editWindowLinesRange.endExclusive);
|
|
223
251
|
const editWindow = currentDocument.transformer.getOffsetRange(new range_1.Range(editWindowLinesRange.start + 1, 1, editWindowLinesRange.endExclusive, editWindowLastLineLength + 1));
|
|
@@ -242,25 +270,25 @@ let XtabProvider = class XtabProvider {
|
|
|
242
270
|
return new statelessNextEditProvider_1.NoNextEditReason.PromptTooLarge('currentFile');
|
|
243
271
|
}
|
|
244
272
|
const { clippedTaggedCurrentDoc, areaAroundCodeToEdit } = taggedCurrentFileContentResult.val;
|
|
245
|
-
|
|
273
|
+
telemetry.setNLinesOfCurrentFileInPrompt(clippedTaggedCurrentDoc.lines.length);
|
|
246
274
|
const { aggressivenessLevel, userHappinessScore } = this.userInteractionMonitor.getAggressivenessLevel();
|
|
247
275
|
// Log user's raw aggressiveness setting when explicitly changed from default
|
|
248
276
|
const userAggressivenessSetting = this.configService.getExperimentBasedConfig(configurationService_1.ConfigKey.Advanced.InlineEditsAggressiveness, this.expService);
|
|
249
|
-
|
|
277
|
+
telemetry.setUserAggressivenessSetting(userAggressivenessSetting);
|
|
250
278
|
// Log aggressiveness level and user happiness score
|
|
251
|
-
|
|
279
|
+
telemetry.setXtabAggressivenessLevel(aggressivenessLevel);
|
|
252
280
|
if (userHappinessScore !== undefined) {
|
|
253
|
-
|
|
281
|
+
telemetry.setXtabUserHappinessScore(userHappinessScore);
|
|
254
282
|
}
|
|
255
|
-
const langCtx = await this.getAndProcessLanguageContext(request, delaySession, activeDocument, cursorPosition, promptOptions, tracer, logContext, cancellationToken);
|
|
283
|
+
const langCtx = await this.getAndProcessLanguageContext(request, delaySession, activeDocument, cursorPosition, promptOptions, { tracer, logContext, telemetry }, cancellationToken);
|
|
256
284
|
if (cancellationToken.isCancellationRequested) {
|
|
257
285
|
return new statelessNextEditProvider_1.NoNextEditReason.GotCancelled('afterLanguageContextAwait');
|
|
258
286
|
}
|
|
259
287
|
const lintErrors = new lintErrors_1.LintErrors(activeDocument.id, currentDocument, this.langDiagService, request.xtabEditHistory);
|
|
260
288
|
const promptPieces = new promptCrafting_1.PromptPieces(currentDocument, editWindowLinesRange, areaAroundEditWindowLinesRange, activeDocument, request.xtabEditHistory, clippedTaggedCurrentDoc.lines, areaAroundCodeToEdit, langCtx, aggressivenessLevel, lintErrors, XtabProvider_1.computeTokens, promptOptions);
|
|
261
289
|
const { prompt: userPrompt, nDiffsInPrompt, diffTokensInPrompt } = (0, promptCrafting_1.getUserPrompt)(promptPieces);
|
|
262
|
-
|
|
263
|
-
|
|
290
|
+
telemetry.setNDiffsInPrompt(nDiffsInPrompt);
|
|
291
|
+
telemetry.setDiffTokensInPrompt(diffTokensInPrompt);
|
|
264
292
|
const responseFormat = xtabPromptOptions.ResponseFormat.fromPromptingStrategy(promptOptions.promptingStrategy);
|
|
265
293
|
const prediction = this.getPredictedOutput(activeDocument, editWindowLines, responseFormat);
|
|
266
294
|
const messages = (0, xtabUtils_1.constructMessages)({
|
|
@@ -268,35 +296,47 @@ let XtabProvider = class XtabProvider {
|
|
|
268
296
|
userMsg: userPrompt,
|
|
269
297
|
});
|
|
270
298
|
logContext.setPrompt(messages);
|
|
271
|
-
|
|
299
|
+
telemetry.setPrompt(messages);
|
|
272
300
|
const HARD_CHAR_LIMIT = 30000 * 4; // 30K tokens, assuming 4 chars per token -- we use approximation here because counting tokens exactly is time-consuming
|
|
273
301
|
const promptCharCount = (0, xtabUtils_1.charCount)(messages);
|
|
274
302
|
if (promptCharCount > HARD_CHAR_LIMIT) {
|
|
275
303
|
return new statelessNextEditProvider_1.NoNextEditReason.PromptTooLarge('final');
|
|
276
304
|
}
|
|
277
|
-
await this.debounce(delaySession, retryState, tracer,
|
|
305
|
+
await this.debounce(delaySession, retryState, tracer, telemetry, cancellationToken);
|
|
278
306
|
if (cancellationToken.isCancellationRequested) {
|
|
279
307
|
return new statelessNextEditProvider_1.NoNextEditReason.GotCancelled('afterDebounce');
|
|
280
308
|
}
|
|
281
309
|
// Fire-and-forget: collect lint errors and terminal output for telemetry in background to avoid blocking the main path
|
|
282
310
|
Promise.resolve().then(() => {
|
|
283
311
|
const lintErrorsData = lintErrors.getData();
|
|
284
|
-
|
|
312
|
+
telemetry.setLintErrors(lintErrorsData);
|
|
285
313
|
logContext.setDiagnosticsData(lintErrorsData);
|
|
286
314
|
const terminalOutputData = this.terminalMonitor.getData();
|
|
287
|
-
|
|
315
|
+
telemetry.setTerminalOutput(terminalOutputData);
|
|
288
316
|
logContext.setTerminalData(terminalOutputData);
|
|
289
317
|
});
|
|
290
318
|
// Fire-and-forget: compute GhostText-style similar files context for telemetry
|
|
291
|
-
|
|
319
|
+
telemetry.setSimilarFilesContext(this.similarFilesContextService.compute(activeDocument.id.uri, activeDocument.languageId, activeDocument.documentAfterEdits.value, currentDocument.cursorOffset));
|
|
292
320
|
request.fetchIssued = true;
|
|
293
|
-
|
|
321
|
+
const editStreamCtx = {
|
|
322
|
+
endpoint,
|
|
323
|
+
modelServiceConfig,
|
|
324
|
+
messages,
|
|
325
|
+
clippedTaggedCurrentDoc,
|
|
326
|
+
editWindowInfo: {
|
|
327
|
+
editWindow,
|
|
328
|
+
editWindowLines,
|
|
329
|
+
cursorOriginalLinesOffset,
|
|
330
|
+
editWindowLineRange: editWindowLinesRange,
|
|
331
|
+
},
|
|
332
|
+
promptPieces,
|
|
333
|
+
prediction,
|
|
334
|
+
originalEditWindow,
|
|
335
|
+
};
|
|
336
|
+
return yield* this.streamEditsWithFiltering(request, editStreamCtx, {
|
|
294
337
|
shouldRemoveCursorTagFromResponse,
|
|
295
338
|
responseFormat,
|
|
296
|
-
|
|
297
|
-
aggressivenessLevel,
|
|
298
|
-
userHappinessScore,
|
|
299
|
-
}, delaySession, tracer, telemetryBuilder, logContext, cancellationToken, originalEditWindow);
|
|
339
|
+
}, { aggressivenessLevel, userHappinessScore }, retryState, delaySession, { tracer, logContext, telemetry }, cancellationToken);
|
|
300
340
|
}
|
|
301
341
|
_configureDebounceTimings(request, currentDocument, promptOptions, telemetry, delaySession, tracer) {
|
|
302
342
|
const isCursorAtEndOfLine = currentDocument.isCursorAtEndOfLine();
|
|
@@ -356,17 +396,17 @@ let XtabProvider = class XtabProvider {
|
|
|
356
396
|
tracer.trace(`Aggressiveness ${userAggressiveness}: min response time set to ${minResponseTimeMs}ms`);
|
|
357
397
|
}
|
|
358
398
|
}
|
|
359
|
-
getAndProcessLanguageContext(request, delaySession, activeDocument, cursorPosition, promptOptions,
|
|
399
|
+
getAndProcessLanguageContext(request, delaySession, activeDocument, cursorPosition, promptOptions, tracing, cancellationToken) {
|
|
360
400
|
const recordingEnabled = this.configService.getConfig(configurationService_1.ConfigKey.TeamInternal.InlineEditsLogContextRecorderEnabled);
|
|
361
401
|
if (!promptOptions.languageContext.enabled && !recordingEnabled) {
|
|
362
402
|
return Promise.resolve(undefined);
|
|
363
403
|
}
|
|
364
|
-
const langCtxPromise = this.getLanguageContext(request, delaySession, activeDocument, cursorPosition,
|
|
404
|
+
const langCtxPromise = this.getLanguageContext(request, delaySession, activeDocument, cursorPosition, tracing, cancellationToken);
|
|
365
405
|
// if recording, add diagnostics for the file to the recording and hook up the language context promise to write to the recording
|
|
366
406
|
if (recordingEnabled) {
|
|
367
407
|
langCtxPromise.then(langCtxs => {
|
|
368
408
|
if (langCtxs) {
|
|
369
|
-
logContext.setLanguageContext(langCtxs);
|
|
409
|
+
tracing.logContext.setLanguageContext(langCtxs);
|
|
370
410
|
}
|
|
371
411
|
});
|
|
372
412
|
}
|
|
@@ -374,7 +414,7 @@ let XtabProvider = class XtabProvider {
|
|
|
374
414
|
? langCtxPromise
|
|
375
415
|
: Promise.resolve(undefined);
|
|
376
416
|
}
|
|
377
|
-
async getLanguageContext(request, delaySession, activeDocument, cursorPosition,
|
|
417
|
+
async getLanguageContext(request, delaySession, activeDocument, cursorPosition, tracing, cancellationToken) {
|
|
378
418
|
try {
|
|
379
419
|
const textDoc = this.workspaceService.textDocuments.find(doc => doc.uri.toString() === activeDocument.id.uri);
|
|
380
420
|
if (textDoc === undefined) {
|
|
@@ -434,14 +474,15 @@ let XtabProvider = class XtabProvider {
|
|
|
434
474
|
return { start, end, items: langCtxItems };
|
|
435
475
|
}
|
|
436
476
|
catch (error) {
|
|
437
|
-
logContext.setError(errors_1.ErrorUtils.fromUnknown(error));
|
|
438
|
-
tracer.trace(`Failed to fetch language context: ${error}`);
|
|
477
|
+
tracing.logContext.setError(errors_1.ErrorUtils.fromUnknown(error));
|
|
478
|
+
tracing.tracer.trace(`Failed to fetch language context: ${error}`);
|
|
439
479
|
return undefined;
|
|
440
480
|
}
|
|
441
481
|
}
|
|
442
|
-
async *streamEditsWithFiltering(request,
|
|
443
|
-
const tracer =
|
|
444
|
-
const
|
|
482
|
+
async *streamEditsWithFiltering(request, editStreamCtx, responseOpts, fetchMetadata, retryState, delaySession, tracing, cancellationToken) {
|
|
483
|
+
const tracer = tracing.tracer.createSubLogger('streamEditsWithFiltering');
|
|
484
|
+
const subTracing = { ...tracing, tracer };
|
|
485
|
+
const iterator = this.streamEdits(request, editStreamCtx, responseOpts, fetchMetadata, retryState, delaySession, subTracing, cancellationToken);
|
|
445
486
|
let nEdits = 0;
|
|
446
487
|
let r = await iterator.next();
|
|
447
488
|
while (!r.done) {
|
|
@@ -461,22 +502,43 @@ let XtabProvider = class XtabProvider {
|
|
|
461
502
|
if (nEdits === 0 &&
|
|
462
503
|
r.value instanceof statelessNextEditProvider_1.NoNextEditReason.NoSuggestions // only retry if there was no error, cancellation, etc.
|
|
463
504
|
) {
|
|
464
|
-
return yield* this.doGetNextEditsWithCursorJump(request,
|
|
505
|
+
return yield* this.doGetNextEditsWithCursorJump(request, editStreamCtx, delaySession, tracing, cancellationToken, retryState);
|
|
465
506
|
}
|
|
466
507
|
return r.value;
|
|
467
508
|
}
|
|
468
|
-
async *streamEdits(request,
|
|
469
|
-
const tracer =
|
|
470
|
-
|
|
509
|
+
async *streamEdits(request, editStreamCtx, responseOpts, fetchMetadata, retryState, delaySession, tracing, cancellationToken) {
|
|
510
|
+
const tracer = tracing.tracer.createSubLogger('streamEdits');
|
|
511
|
+
// Create a local cancellation source linked to the caller's token.
|
|
512
|
+
// This lets us cancel the fetch immediately on cursor-line divergence
|
|
513
|
+
// without reaching into the request's CancellationTokenSource (which
|
|
514
|
+
// is owned by nextEditProvider.ts).
|
|
515
|
+
const fetchCts = new cancellation_1.CancellationTokenSource(cancellationToken);
|
|
516
|
+
const fetchCancellationToken = fetchCts.token;
|
|
517
|
+
try {
|
|
518
|
+
return yield* this._streamEditsImpl(request, editStreamCtx, responseOpts, fetchMetadata, retryState, delaySession, { ...tracing, tracer }, cancellationToken, fetchCts, fetchCancellationToken);
|
|
519
|
+
}
|
|
520
|
+
finally {
|
|
521
|
+
fetchCts.dispose();
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Initiates the HTTP fetch, sets up the streaming pipeline, and returns either
|
|
526
|
+
* a clean line stream (with cursor-tag removal and latency logging applied)
|
|
527
|
+
* or an error / retry signal.
|
|
528
|
+
*
|
|
529
|
+
* This method encapsulates all fetch infrastructure so that downstream response
|
|
530
|
+
* format handlers only need an `AsyncIterable<string>` line stream.
|
|
531
|
+
*/
|
|
532
|
+
async _performFetch(endpoint, messages, prediction, requestId, fetchMetadata, shouldRemoveCursorTagFromResponse, editWindow, documentBeforeEdits, fetchCancellationToken, tracing) {
|
|
533
|
+
const { tracer, logContext, telemetry } = tracing;
|
|
471
534
|
const useFetcher = this.configService.getExperimentBasedConfig(configurationService_1.ConfigKey.NextEditSuggestionsFetcher, this.expService) || undefined;
|
|
472
535
|
const fetchStreamSource = new chatMLFetcher_1.FetchStreamSource();
|
|
473
536
|
const fetchRequestStopWatch = new stopwatch_1.StopWatch();
|
|
474
537
|
let responseSoFar = '';
|
|
475
|
-
let chatResponseFailure;
|
|
476
538
|
let ttft;
|
|
477
539
|
const firstTokenReceived = new async_2.DeferredPromise();
|
|
478
|
-
logContext.setHeaderRequestId(
|
|
479
|
-
|
|
540
|
+
logContext.setHeaderRequestId(requestId);
|
|
541
|
+
telemetry.setFetchStartedAt();
|
|
480
542
|
logContext.setFetchStartTime();
|
|
481
543
|
// we must not await this promise because we want to stream edits as they come in
|
|
482
544
|
const fetchResultPromise = endpoint.makeChatRequest2({
|
|
@@ -504,48 +566,51 @@ let XtabProvider = class XtabProvider {
|
|
|
504
566
|
},
|
|
505
567
|
userInitiatedRequest: undefined,
|
|
506
568
|
telemetryProperties: {
|
|
507
|
-
requestId
|
|
569
|
+
requestId,
|
|
508
570
|
},
|
|
509
571
|
useFetcher,
|
|
510
572
|
customMetadata: {
|
|
511
|
-
aggressivenessLevel:
|
|
512
|
-
userHappinessScore:
|
|
573
|
+
aggressivenessLevel: fetchMetadata.aggressivenessLevel,
|
|
574
|
+
userHappinessScore: fetchMetadata.userHappinessScore,
|
|
513
575
|
},
|
|
514
|
-
},
|
|
515
|
-
|
|
576
|
+
}, fetchCancellationToken);
|
|
577
|
+
telemetry.setResponse(fetchResultPromise.then((response) => ({ response, ttft })));
|
|
516
578
|
logContext.setFullResponse(fetchResultPromise.then((response) => response.type === commonTypes_1.ChatFetchResponseType.Success ? response.value : undefined));
|
|
517
|
-
const fetchRes = await Promise.race([firstTokenReceived.p, fetchResultPromise]);
|
|
518
|
-
if (fetchRes && fetchRes.type !== commonTypes_1.ChatFetchResponseType.Success) {
|
|
519
|
-
if (fetchRes.type === commonTypes_1.ChatFetchResponseType.NotFound &&
|
|
520
|
-
!this.forceUseDefaultModel // if we haven't already forced using the default model; otherwise, this could cause an infinite loop
|
|
521
|
-
) {
|
|
522
|
-
this.forceUseDefaultModel = true;
|
|
523
|
-
return yield* this.doGetNextEdit(request, delaySession, tracer, logContext, cancellationToken, telemetryBuilder, opts.retryState); // use the same retry state
|
|
524
|
-
}
|
|
525
|
-
// diff-patch based model returns no choices if it has no edits to suggest
|
|
526
|
-
if (fetchRes.type === commonTypes_1.ChatFetchResponseType.Unknown && fetchRes.reason === commonTypes_1.RESPONSE_CONTAINED_NO_CHOICES) {
|
|
527
|
-
return new statelessNextEditProvider_1.NoNextEditReason.NoSuggestions(request.documentBeforeEdits, editWindow);
|
|
528
|
-
}
|
|
529
|
-
return mapChatFetcherErrorToNoNextEditReason(fetchRes);
|
|
530
|
-
}
|
|
531
579
|
fetchResultPromise
|
|
532
580
|
.then((response) => {
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
581
|
+
if (response.type !== commonTypes_1.ChatFetchResponseType.Success) {
|
|
582
|
+
fetchStreamSource.reject(new fetchStreamError_1.FetchStreamError(mapChatFetcherErrorToNoNextEditReason(response)));
|
|
583
|
+
}
|
|
584
|
+
else {
|
|
585
|
+
fetchStreamSource.resolve();
|
|
586
|
+
}
|
|
536
587
|
})
|
|
537
588
|
.catch((err) => {
|
|
538
589
|
// in principle this shouldn't happen because ChatMLFetcher's fetchOne should not throw
|
|
539
590
|
logContext.setError(errors_1.ErrorUtils.fromUnknown(err));
|
|
540
591
|
logContext.addLog(`ChatMLFetcher fetch call threw -- this's UNEXPECTED!`);
|
|
592
|
+
fetchStreamSource.reject(errors_1.ErrorUtils.fromUnknown(err));
|
|
541
593
|
}).finally(() => {
|
|
542
594
|
logContext.setFetchEndTime();
|
|
543
595
|
if (!firstTokenReceived.isSettled) {
|
|
544
596
|
firstTokenReceived.complete();
|
|
545
597
|
}
|
|
546
|
-
fetchStreamSource.resolve();
|
|
547
598
|
logContext.setResponse(responseSoFar);
|
|
548
599
|
});
|
|
600
|
+
const fetchRes = await Promise.race([firstTokenReceived.p, fetchResultPromise]);
|
|
601
|
+
if (fetchRes && fetchRes.type !== commonTypes_1.ChatFetchResponseType.Success) {
|
|
602
|
+
if (fetchRes.type === commonTypes_1.ChatFetchResponseType.NotFound &&
|
|
603
|
+
!this.forceUseDefaultModel // if we haven't already forced using the default model; otherwise, this could cause an infinite loop
|
|
604
|
+
) {
|
|
605
|
+
this.forceUseDefaultModel = true;
|
|
606
|
+
return FetchResult.ModelNotFound.INSTANCE;
|
|
607
|
+
}
|
|
608
|
+
// diff-patch based model returns no choices if it has no edits to suggest
|
|
609
|
+
if (fetchRes.type === commonTypes_1.ChatFetchResponseType.Unknown && fetchRes.reason === commonTypes_1.RESPONSE_CONTAINED_NO_CHOICES) {
|
|
610
|
+
return new FetchResult.FetchFailure(new statelessNextEditProvider_1.NoNextEditReason.NoSuggestions(documentBeforeEdits, editWindow));
|
|
611
|
+
}
|
|
612
|
+
return new FetchResult.FetchFailure(mapChatFetcherErrorToNoNextEditReason(fetchRes));
|
|
613
|
+
}
|
|
549
614
|
const llmLinesStream = asyncIterableUtils_1.AsyncIterUtilsExt.splitLines(asyncIterableUtils_1.AsyncIterUtils.map(fetchStreamSource.stream, (chunk) => chunk.delta.text));
|
|
550
615
|
// logging of times
|
|
551
616
|
// removal of cursor tag if option is set
|
|
@@ -554,119 +619,132 @@ let XtabProvider = class XtabProvider {
|
|
|
554
619
|
for await (const v of llmLinesStream) {
|
|
555
620
|
const trace = `Line ${i++} emitted with latency ${fetchRequestStopWatch.elapsed()} ms`;
|
|
556
621
|
tracer.trace(trace);
|
|
557
|
-
yield
|
|
622
|
+
yield shouldRemoveCursorTagFromResponse
|
|
558
623
|
? v.replaceAll(tags_1.PromptTags.CURSOR, '')
|
|
559
624
|
: v;
|
|
560
625
|
}
|
|
561
626
|
})();
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
627
|
+
return new FetchResult.Lines(linesStream, () => responseSoFar, fetchRequestStopWatch);
|
|
628
|
+
}
|
|
629
|
+
async *_streamEditsImpl(request, editStreamCtx, responseOpts, fetchMetadata, retryState, delaySession, tracing, cancellationToken, fetchCts, fetchCancellationToken) {
|
|
630
|
+
const { tracer, logContext, telemetry } = tracing;
|
|
631
|
+
const { endpoint, messages, clippedTaggedCurrentDoc, editWindowInfo, promptPieces, prediction, originalEditWindow } = editStreamCtx;
|
|
632
|
+
const { editWindow, editWindowLines, cursorOriginalLinesOffset, editWindowLineRange } = editWindowInfo;
|
|
633
|
+
const targetDocument = request.getActiveDocument().id;
|
|
634
|
+
// Phase 1: Fetch lifecycle — initiate HTTP request and produce a clean line stream
|
|
635
|
+
const fetchResult = await this._performFetch(endpoint, messages, prediction, request.headerRequestId, fetchMetadata, responseOpts.shouldRemoveCursorTagFromResponse, editWindow, request.documentBeforeEdits, fetchCancellationToken, tracing);
|
|
636
|
+
if (fetchResult instanceof FetchResult.ModelNotFound) {
|
|
637
|
+
return yield* this.doGetNextEdit(request, delaySession, tracing, cancellationToken, retryState);
|
|
638
|
+
}
|
|
639
|
+
if (fetchResult instanceof FetchResult.FetchFailure) {
|
|
640
|
+
return fetchResult.reason;
|
|
641
|
+
}
|
|
642
|
+
const { linesStream, getResponseSoFar, fetchRequestStopWatch } = fetchResult;
|
|
643
|
+
// Phase 2: Dispatch to the appropriate response format handler
|
|
644
|
+
const isFromCursorJump = retryState instanceof RetryState.Retrying && retryState.reason === 'cursorJump';
|
|
645
|
+
let parseResult;
|
|
646
|
+
try {
|
|
647
|
+
switch (responseOpts.responseFormat) {
|
|
648
|
+
case xtabPromptOptions.ResponseFormat.EditWindowOnly: {
|
|
649
|
+
parseResult = (0, responseFormatHandlers_1.handleEditWindowOnly)(linesStream);
|
|
650
|
+
break;
|
|
651
|
+
}
|
|
652
|
+
case xtabPromptOptions.ResponseFormat.CodeBlock: {
|
|
653
|
+
parseResult = (0, responseFormatHandlers_1.handleCodeBlock)(linesStream);
|
|
654
|
+
break;
|
|
655
|
+
}
|
|
656
|
+
case xtabPromptOptions.ResponseFormat.EditWindowWithEditIntent:
|
|
657
|
+
case xtabPromptOptions.ResponseFormat.EditWindowWithEditIntentShort: {
|
|
658
|
+
const parseMode = responseOpts.responseFormat === xtabPromptOptions.ResponseFormat.EditWindowWithEditIntentShort
|
|
659
|
+
? editIntent_1.EditIntentParseMode.ShortName
|
|
660
|
+
: editIntent_1.EditIntentParseMode.Tags;
|
|
661
|
+
parseResult = await (0, responseFormatHandlers_1.handleEditWindowWithEditIntent)(linesStream, tracer, parseMode);
|
|
662
|
+
break;
|
|
663
|
+
}
|
|
664
|
+
case xtabPromptOptions.ResponseFormat.CustomDiffPatch: {
|
|
665
|
+
const activeDoc = request.getActiveDocument();
|
|
666
|
+
const currentDocument = promptPieces.currentDocument;
|
|
667
|
+
const lastLine = currentDocument.lines[clippedTaggedCurrentDoc.keptRange.endExclusive - 1];
|
|
668
|
+
const lastLineLength = lastLine.length;
|
|
669
|
+
const pseudoEditWindow = currentDocument.transformer.getOffsetRange(new range_1.Range(clippedTaggedCurrentDoc.keptRange.start + 1, 1, clippedTaggedCurrentDoc.keptRange.endExclusive, lastLineLength + 1));
|
|
670
|
+
parseResult = new responseFormatHandlers_1.ResponseParseResult.DirectEdits(xtabCustomDiffPatchResponseHandler_1.XtabCustomDiffPatchResponseHandler.handleResponse(linesStream, currentDocument, activeDoc.id, activeDoc.workspaceRoot, pseudoEditWindow, tracer));
|
|
671
|
+
break;
|
|
672
|
+
}
|
|
673
|
+
case xtabPromptOptions.ResponseFormat.UnifiedWithXml: {
|
|
674
|
+
parseResult = await (0, responseFormatHandlers_1.handleUnifiedWithXml)(linesStream, {
|
|
675
|
+
editWindowLines,
|
|
676
|
+
editWindowLineRange,
|
|
677
|
+
cursorOriginalLinesOffset,
|
|
678
|
+
cursorColumnZeroBased: promptPieces.currentDocument.cursorPosition.column - 1,
|
|
679
|
+
editWindow,
|
|
680
|
+
originalEditWindow,
|
|
681
|
+
targetDocument,
|
|
682
|
+
isFromCursorJump,
|
|
683
|
+
}, request.documentBeforeEdits, tracer);
|
|
684
|
+
break;
|
|
685
|
+
}
|
|
686
|
+
default:
|
|
687
|
+
(0, assert_1.assertNever)(responseOpts.responseFormat);
|
|
601
688
|
}
|
|
602
|
-
|
|
603
|
-
|
|
689
|
+
// Handle result uniformly
|
|
690
|
+
if (parseResult instanceof responseFormatHandlers_1.ResponseParseResult.Done) {
|
|
691
|
+
return parseResult.reason;
|
|
604
692
|
}
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
return yield* this.doGetNextEditsWithCursorJump(request, modelServiceConfig, editWindow, promptPieces, delaySession, tracer, logContext, cancellationToken, telemetryBuilder, opts.retryState);
|
|
693
|
+
if (parseResult instanceof responseFormatHandlers_1.ResponseParseResult.DirectEdits) {
|
|
694
|
+
return yield* parseResult.stream;
|
|
608
695
|
}
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
696
|
+
// parseResult is EditWindowLines — log edit-intent telemetry and apply aggressiveness filter
|
|
697
|
+
if (parseResult.editIntentMetadata) {
|
|
698
|
+
const { intent, parseError } = parseResult.editIntentMetadata;
|
|
699
|
+
telemetry.setEditIntent(intent);
|
|
700
|
+
if (parseError) {
|
|
701
|
+
telemetry.setEditIntentParseError(parseError);
|
|
613
702
|
}
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
const lines = [];
|
|
618
|
-
let v = await linesIter.next();
|
|
619
|
-
while (!v.done) {
|
|
620
|
-
if (v.value.includes(tags_1.ResponseTags.INSERT.end)) {
|
|
621
|
-
break;
|
|
622
|
-
}
|
|
623
|
-
else {
|
|
624
|
-
lines.push(v.value);
|
|
625
|
-
}
|
|
626
|
-
v = await linesIter.next();
|
|
703
|
+
if (!xtabPromptOptions.EditIntent.shouldShowEdit(intent, promptPieces.aggressivenessLevel)) {
|
|
704
|
+
tracer.trace(`Filtered out edit due to edit intent "${intent}" with aggressiveness "${promptPieces.aggressivenessLevel}"`);
|
|
705
|
+
return new statelessNextEditProvider_1.NoNextEditReason.FilteredOut(`editIntent:${intent} aggressivenessLevel:${promptPieces.aggressivenessLevel}`);
|
|
627
706
|
}
|
|
628
|
-
const line = editWindowLineRange.start + cursorOriginalLinesOffset + 2;
|
|
629
|
-
yield {
|
|
630
|
-
edit: new lineEdit_1.LineReplacement(new lineRange_1.LineRange(line, line), lines),
|
|
631
|
-
isFromCursorJump,
|
|
632
|
-
window: editWindow,
|
|
633
|
-
originalWindow: originalEditWindow,
|
|
634
|
-
targetDocument,
|
|
635
|
-
};
|
|
636
|
-
return new statelessNextEditProvider_1.NoNextEditReason.NoSuggestions(request.documentBeforeEdits, editWindow);
|
|
637
707
|
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
708
|
+
const cleanedLinesStream = parseResult.lines;
|
|
709
|
+
const diffOptions = {
|
|
710
|
+
emitFastCursorLineChange: responseProcessor_1.ResponseProcessor.mapEmitFastCursorLineChange(this.configService.getExperimentBasedConfig(configurationService_1.ConfigKey.TeamInternal.InlineEditsXtabProviderEmitFastCursorLineChange, this.expService)),
|
|
711
|
+
nLinesToConverge: this.configService.getExperimentBasedConfig(configurationService_1.ConfigKey.TeamInternal.InlineEditsXtabNNonSignificantLinesToConverge, this.expService),
|
|
712
|
+
nSignificantLinesToConverge: this.configService.getExperimentBasedConfig(configurationService_1.ConfigKey.TeamInternal.InlineEditsXtabNSignificantLinesToConverge, this.expService),
|
|
713
|
+
};
|
|
714
|
+
tracer.trace(`starting to diff stream against edit window lines with latency ${fetchRequestStopWatch.elapsed()} ms`);
|
|
715
|
+
// Wrap the line stream to detect early divergence between the user's
|
|
716
|
+
// intermediate edits and the model's streamed output.
|
|
717
|
+
// In `Cursor` mode only the cursor line is checked; in `EditWindow`
|
|
718
|
+
// mode every line in the edit window is checked.
|
|
719
|
+
//
|
|
720
|
+
// We check compatibility using `isModelLineCompatible`: the user's
|
|
721
|
+
// line change must be contained within the model's line change range
|
|
722
|
+
// and match via the helper's `startsWith` / auto-close subsequence rules.
|
|
723
|
+
const earlyDivergenceMode = (0, backwardCompatSetting_1.backwardCompatSetting)(this.configService.getExperimentBasedConfig(configurationService_1.ConfigKey.TeamInternal.InlineEditsXtabEarlyCursorLineDivergenceCancellation, this.expService), (value) => {
|
|
724
|
+
switch (value) {
|
|
725
|
+
case false:
|
|
726
|
+
case undefined:
|
|
727
|
+
return xtabPromptOptions_1.EarlyDivergenceCancellationMode.Off;
|
|
728
|
+
case true:
|
|
729
|
+
return xtabPromptOptions_1.EarlyDivergenceCancellationMode.Cursor;
|
|
730
|
+
case xtabPromptOptions_1.EarlyDivergenceCancellationMode.Off:
|
|
731
|
+
case xtabPromptOptions_1.EarlyDivergenceCancellationMode.Cursor:
|
|
732
|
+
case xtabPromptOptions_1.EarlyDivergenceCancellationMode.EditWindow:
|
|
733
|
+
return value;
|
|
734
|
+
default:
|
|
735
|
+
return xtabPromptOptions_1.EarlyDivergenceCancellationMode.Off;
|
|
736
|
+
}
|
|
737
|
+
});
|
|
738
|
+
let lineDiverged = false;
|
|
739
|
+
const divergenceCheckedStream = earlyDivergenceMode === xtabPromptOptions_1.EarlyDivergenceCancellationMode.Off
|
|
740
|
+
? cleanedLinesStream
|
|
741
|
+
: linesWithIntermediateEditDivergenceCheck(cleanedLinesStream, cursorOriginalLinesOffset, request, editWindowLineRange, editWindowLines, fetchCts, tracing, (value) => { lineDiverged = value; }, earlyDivergenceMode);
|
|
742
|
+
let i = 0;
|
|
743
|
+
let hasBeenDelayed = false;
|
|
744
|
+
for await (const edit of responseProcessor_1.ResponseProcessor.diff(editWindowLines, divergenceCheckedStream, cursorOriginalLinesOffset, diffOptions)) {
|
|
745
|
+
if (lineDiverged) {
|
|
746
|
+
break;
|
|
747
|
+
}
|
|
670
748
|
tracer.trace(`ResponseProcessor streamed edit #${i} with latency ${fetchRequestStopWatch.elapsed()} ms`);
|
|
671
749
|
const singleLineEdits = [];
|
|
672
750
|
if (edit.lineRange.startLineNumber === edit.lineRange.endLineNumberExclusive || // we don't want to run diff on insertion
|
|
@@ -690,15 +768,12 @@ let XtabProvider = class XtabProvider {
|
|
|
690
768
|
singleLineEdits.push(singleLineEdit);
|
|
691
769
|
}
|
|
692
770
|
}
|
|
693
|
-
|
|
694
|
-
break;
|
|
695
|
-
}
|
|
696
|
-
logContext.setResponse(responseSoFar);
|
|
771
|
+
logContext.setResponse(getResponseSoFar());
|
|
697
772
|
for (const singleLineEdit of singleLineEdits) {
|
|
698
773
|
tracer.trace(`extracting edit #${i}: ${singleLineEdit.toString()}`);
|
|
699
774
|
if (!hasBeenDelayed) { // delay only the first one
|
|
700
775
|
hasBeenDelayed = true;
|
|
701
|
-
const artificialDelay = this.determineArtificialDelayMs(delaySession, tracer,
|
|
776
|
+
const artificialDelay = this.determineArtificialDelayMs(delaySession, tracer, telemetry);
|
|
702
777
|
if (artificialDelay) {
|
|
703
778
|
await (0, async_2.timeout)(artificialDelay);
|
|
704
779
|
tracer.trace(`Artificial delay of ${artificialDelay} ms completed`);
|
|
@@ -711,20 +786,24 @@ let XtabProvider = class XtabProvider {
|
|
|
711
786
|
i++;
|
|
712
787
|
}
|
|
713
788
|
}
|
|
714
|
-
if (
|
|
715
|
-
return
|
|
789
|
+
if (lineDiverged) {
|
|
790
|
+
return new statelessNextEditProvider_1.NoNextEditReason.GotCancelled(earlyDivergenceMode === xtabPromptOptions_1.EarlyDivergenceCancellationMode.Cursor ? 'cursorLineDiverged' : 'editWindowLineDiverged');
|
|
716
791
|
}
|
|
717
792
|
return new statelessNextEditProvider_1.NoNextEditReason.NoSuggestions(request.documentBeforeEdits, editWindow);
|
|
718
793
|
}
|
|
719
794
|
catch (err) {
|
|
795
|
+
if (err instanceof fetchStreamError_1.FetchStreamError) {
|
|
796
|
+
return err.reason;
|
|
797
|
+
}
|
|
720
798
|
logContext.setError(err);
|
|
721
|
-
// Properly handle the error by pushing it as a result
|
|
722
799
|
return new statelessNextEditProvider_1.NoNextEditReason.Unexpected(errors_1.ErrorUtils.fromUnknown(err));
|
|
723
800
|
}
|
|
724
801
|
}
|
|
725
|
-
async *doGetNextEditsWithCursorJump(request,
|
|
802
|
+
async *doGetNextEditsWithCursorJump(request, editStreamCtx, delaySession, tracing, cancellationToken, retryState) {
|
|
803
|
+
const { tracer, telemetry } = tracing;
|
|
804
|
+
const { editWindowInfo: { editWindow }, modelServiceConfig, promptPieces } = editStreamCtx;
|
|
726
805
|
const noSuggestions = new statelessNextEditProvider_1.NoNextEditReason.NoSuggestions(request.documentBeforeEdits, editWindow);
|
|
727
|
-
const nextCursorLinePrediction = this.nextCursorPredictor.determineEnablement(
|
|
806
|
+
const nextCursorLinePrediction = this.nextCursorPredictor.determineEnablement(modelServiceConfig.supportsNextCursorLinePrediction);
|
|
728
807
|
if (nextCursorLinePrediction === undefined || retryState instanceof RetryState.Retrying) {
|
|
729
808
|
return noSuggestions;
|
|
730
809
|
}
|
|
@@ -732,7 +811,7 @@ let XtabProvider = class XtabProvider {
|
|
|
732
811
|
tracer.trace('Skipping cursor prediction: user typed during request');
|
|
733
812
|
return new statelessNextEditProvider_1.NoNextEditReason.GotCancelled('beforeNextCursorPredictionFetchUserTyped');
|
|
734
813
|
}
|
|
735
|
-
const nextCursorLineR = await this.nextCursorPredictor.predictNextCursorPosition(promptPieces, tracer,
|
|
814
|
+
const nextCursorLineR = await this.nextCursorPredictor.predictNextCursorPosition(promptPieces, tracer, telemetry, cancellationToken);
|
|
736
815
|
if (cancellationToken.isCancellationRequested) {
|
|
737
816
|
return new statelessNextEditProvider_1.NoNextEditReason.GotCancelled('afterNextCursorPredictionFetch');
|
|
738
817
|
}
|
|
@@ -742,26 +821,26 @@ let XtabProvider = class XtabProvider {
|
|
|
742
821
|
}
|
|
743
822
|
if (nextCursorLineR.isError()) {
|
|
744
823
|
tracer.trace(`Predicted next cursor line error: ${nextCursorLineR.err.message}`);
|
|
745
|
-
|
|
824
|
+
telemetry.setNextCursorLineError(nextCursorLineR.err.message);
|
|
746
825
|
return noSuggestions;
|
|
747
826
|
}
|
|
748
827
|
const prediction = nextCursorLineR.val;
|
|
749
828
|
if (prediction.kind === 'differentFile') {
|
|
750
|
-
return yield* this.handleCrossFilePrediction(prediction, nextCursorLinePrediction, request,
|
|
829
|
+
return yield* this.handleCrossFilePrediction(prediction, nextCursorLinePrediction, request, editStreamCtx, delaySession, tracing, cancellationToken);
|
|
751
830
|
}
|
|
752
831
|
const nextCursorLineZeroBased = prediction.lineNumber;
|
|
753
832
|
const lineDistanceFromCursorLine = nextCursorLineZeroBased - promptPieces.currentDocument.cursorLineOffset;
|
|
754
|
-
|
|
755
|
-
|
|
833
|
+
telemetry.setNextCursorLineDistance(lineDistanceFromCursorLine);
|
|
834
|
+
telemetry.setNextCursorIsCrossFile(false);
|
|
756
835
|
tracer.trace(`Predicted next cursor line: ${nextCursorLineZeroBased}`);
|
|
757
836
|
if (nextCursorLineZeroBased >= promptPieces.currentDocument.lines.length) { // >= because the line index is zero-based
|
|
758
837
|
tracer.trace(`Predicted next cursor line error: exceedsDocumentLines`);
|
|
759
|
-
|
|
838
|
+
telemetry.setNextCursorLineError('exceedsDocumentLines');
|
|
760
839
|
return noSuggestions;
|
|
761
840
|
}
|
|
762
841
|
if (promptPieces.editWindowLinesRange.contains(nextCursorLineZeroBased)) {
|
|
763
842
|
tracer.trace(`Predicted next cursor line error: withinEditWindow`);
|
|
764
|
-
|
|
843
|
+
telemetry.setNextCursorLineError('withinEditWindow');
|
|
765
844
|
return noSuggestions;
|
|
766
845
|
}
|
|
767
846
|
const nextCursorLineOneBased = nextCursorLineZeroBased + 1;
|
|
@@ -774,7 +853,7 @@ let XtabProvider = class XtabProvider {
|
|
|
774
853
|
return new statelessNextEditProvider_1.NoNextEditReason.NoSuggestions(request.documentBeforeEdits, editWindow, nextCursorPosition);
|
|
775
854
|
}
|
|
776
855
|
case nextCursorLinePrediction_1.NextCursorLinePrediction.OnlyWithEdit: {
|
|
777
|
-
const v = this.doGetNextEditWithSelection(request, new range_1.Range(nextCursorLineOneBased, nextCursorColumn, nextCursorLineOneBased, nextCursorColumn), delaySession,
|
|
856
|
+
const v = this.doGetNextEditWithSelection(request, new range_1.Range(nextCursorLineOneBased, nextCursorColumn, nextCursorLineOneBased, nextCursorColumn), delaySession, tracing, cancellationToken, new RetryState.Retrying('cursorJump'), editWindow);
|
|
778
857
|
return yield* v;
|
|
779
858
|
}
|
|
780
859
|
default: {
|
|
@@ -782,11 +861,13 @@ let XtabProvider = class XtabProvider {
|
|
|
782
861
|
}
|
|
783
862
|
}
|
|
784
863
|
}
|
|
785
|
-
async *handleCrossFilePrediction(prediction, nextCursorLinePrediction, request,
|
|
864
|
+
async *handleCrossFilePrediction(prediction, nextCursorLinePrediction, request, editStreamCtx, delaySession, tracing, cancellationToken) {
|
|
865
|
+
const { tracer, telemetry } = tracing;
|
|
866
|
+
const { editWindowInfo: { editWindow }, promptPieces } = editStreamCtx;
|
|
786
867
|
const workspaceRoot = promptPieces.activeDoc.workspaceRoot;
|
|
787
868
|
if (!workspaceRoot && !(0, path_1.isAbsolute)(prediction.filePath)) {
|
|
788
869
|
tracer.trace('Predicted cross-file cursor jump error: noWorkspaceRoot');
|
|
789
|
-
|
|
870
|
+
telemetry.setNextCursorLineError('crossFile:noWorkspaceRoot');
|
|
790
871
|
return new statelessNextEditProvider_1.NoNextEditReason.NoSuggestions(request.documentBeforeEdits, editWindow);
|
|
791
872
|
}
|
|
792
873
|
const targetUri = (0, path_1.isAbsolute)(prediction.filePath)
|
|
@@ -795,7 +876,7 @@ let XtabProvider = class XtabProvider {
|
|
|
795
876
|
const targetDocumentId = documentId_1.DocumentId.create(targetUri.toString());
|
|
796
877
|
const nextCursorLineOneBased = prediction.lineNumber + 1;
|
|
797
878
|
const nextCursorPosition = new position_1.Position(nextCursorLineOneBased, 1);
|
|
798
|
-
|
|
879
|
+
telemetry.setNextCursorIsCrossFile(true);
|
|
799
880
|
tracer.trace(`Predicted cross-file cursor jump: ${prediction.filePath}:${prediction.lineNumber}`);
|
|
800
881
|
switch (nextCursorLinePrediction) {
|
|
801
882
|
case nextCursorLinePrediction_1.NextCursorLinePrediction.Jump: {
|
|
@@ -808,7 +889,7 @@ let XtabProvider = class XtabProvider {
|
|
|
808
889
|
}
|
|
809
890
|
catch (err) {
|
|
810
891
|
tracer.trace(`Failed to open target file for cross-file edit: ${errors_1.ErrorUtils.fromUnknown(err).message}`);
|
|
811
|
-
|
|
892
|
+
telemetry.setNextCursorLineError('crossFile:failedToOpenFile');
|
|
812
893
|
return new statelessNextEditProvider_1.NoNextEditReason.NoSuggestions(request.documentBeforeEdits, editWindow, nextCursorPosition, targetDocumentId);
|
|
813
894
|
}
|
|
814
895
|
if (cancellationToken.isCancellationRequested) {
|
|
@@ -821,7 +902,7 @@ let XtabProvider = class XtabProvider {
|
|
|
821
902
|
const targetContent = new abstractText_1.StringText(targetTextDoc.getText());
|
|
822
903
|
const syntheticDoc = new statelessNextEditProvider_1.StatelessNextEditDocument(targetDocumentId, promptPieces.activeDoc.workspaceRoot, languageId_1.LanguageId.create(targetTextDoc.languageId), targetContent.getLines(), lineEdit_1.LineEdit.empty, targetContent, new edit_1.Edits(stringEdit_1.StringEdit, []));
|
|
823
904
|
const syntheticRequest = new statelessNextEditProvider_1.StatelessNextEditRequest(request.headerRequestId, request.opportunityId, targetContent, [syntheticDoc], 0, request.xtabEditHistory, new async_2.DeferredPromise(), request.expandedEditWindowNLines, request.isSpeculative, request.logContext, request.recordingBookmark, request.recording, request.providerRequestStartDateTime);
|
|
824
|
-
return yield* this.doGetNextEditWithSelection(syntheticRequest, new range_1.Range(nextCursorLineOneBased, 1, nextCursorLineOneBased, 1), delaySession,
|
|
905
|
+
return yield* this.doGetNextEditWithSelection(syntheticRequest, new range_1.Range(nextCursorLineOneBased, 1, nextCursorLineOneBased, 1), delaySession, tracing, cancellationToken, new RetryState.Retrying('cursorJump'), editWindow);
|
|
825
906
|
}
|
|
826
907
|
default: {
|
|
827
908
|
(0, assert_1.assertNever)(nextCursorLinePrediction);
|
|
@@ -873,7 +954,7 @@ let XtabProvider = class XtabProvider {
|
|
|
873
954
|
const maxMergeConflictLines = this.configService.getExperimentBasedConfig(configurationService_1.ConfigKey.TeamInternal.InlineEditsXtabMaxMergeConflictLines, this.expService);
|
|
874
955
|
if (maxMergeConflictLines) {
|
|
875
956
|
const tentativeEditWindow = new offsetRange_1.OffsetRange(codeToEditStart, codeToEditEndExcl);
|
|
876
|
-
const mergeConflictRange = findMergeConflictMarkersRange(currentDocLines, tentativeEditWindow, maxMergeConflictLines);
|
|
957
|
+
const mergeConflictRange = (0, xtabUtils_1.findMergeConflictMarkersRange)(currentDocLines, tentativeEditWindow, maxMergeConflictLines);
|
|
877
958
|
if (mergeConflictRange) {
|
|
878
959
|
const onlyMergeConflictLines = this.configService.getExperimentBasedConfig(configurationService_1.ConfigKey.TeamInternal.InlineEditsXtabOnlyMergeConflictLines, this.expService);
|
|
879
960
|
telemetry.setMergeConflictExpanded(onlyMergeConflictLines ? 'only' : 'normal');
|
|
@@ -1191,176 +1272,49 @@ function getPredictionContents(doc, editWindowLines, responseFormat) {
|
|
|
1191
1272
|
(0, assert_1.assertNever)(responseFormat);
|
|
1192
1273
|
}
|
|
1193
1274
|
}
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
/** Parse using XML-style tags: <|edit_intent|>value<|/edit_intent|> */
|
|
1200
|
-
EditIntentParseMode["Tags"] = "tags";
|
|
1201
|
-
/** Parse using short names on the first line: N|L|M|H */
|
|
1202
|
-
EditIntentParseMode["ShortName"] = "shortName";
|
|
1203
|
-
})(EditIntentParseMode || (exports.EditIntentParseMode = EditIntentParseMode = {}));
|
|
1204
|
-
/**
|
|
1205
|
-
* Parses the edit_intent from the first line of the response stream.
|
|
1206
|
-
* The edit_intent MUST be on the first line, otherwise it's treated as not provided.
|
|
1207
|
-
* Returns the parsed EditIntent and a new stream with the remaining content.
|
|
1208
|
-
*
|
|
1209
|
-
* Supports two modes:
|
|
1210
|
-
* - Tags (default): <|edit_intent|>low|medium|high|no_edit<|/edit_intent|>
|
|
1211
|
-
* - ShortName: N|L|M|H on the first line
|
|
1212
|
-
*
|
|
1213
|
-
* @param linesStream The stream of lines from the model response
|
|
1214
|
-
* @param tracer Logger for tracing
|
|
1215
|
-
* @param mode The parse mode (Tags or ShortName), defaults to Tags
|
|
1216
|
-
*/
|
|
1217
|
-
async function parseEditIntentFromStream(linesStream, tracer, mode = EditIntentParseMode.Tags) {
|
|
1218
|
-
if (mode === EditIntentParseMode.ShortName) {
|
|
1219
|
-
return parseEditIntentFromStreamShortName(linesStream, tracer);
|
|
1220
|
-
}
|
|
1221
|
-
return parseEditIntentFromStreamTags(linesStream, tracer);
|
|
1222
|
-
}
|
|
1223
|
-
/**
|
|
1224
|
-
* Parses the edit_intent using short name format (N|L|M|H on first line).
|
|
1225
|
-
*/
|
|
1226
|
-
async function parseEditIntentFromStreamShortName(linesStream, tracer) {
|
|
1227
|
-
let editIntent = xtabPromptOptions.EditIntent.High; // Default to high (always show) if no short name found
|
|
1228
|
-
let parseError;
|
|
1229
|
-
const linesIter = linesStream[Symbol.asyncIterator]();
|
|
1230
|
-
const firstLineResult = await linesIter.next();
|
|
1231
|
-
if (firstLineResult.done) {
|
|
1232
|
-
// Empty stream
|
|
1233
|
-
parseError = 'emptyResponse';
|
|
1234
|
-
tracer.warn(`Empty response stream, no edit_intent short name found`);
|
|
1235
|
-
const remainingLinesStream = (async function* () { })();
|
|
1236
|
-
return { editIntent, remainingLinesStream, parseError };
|
|
1237
|
-
}
|
|
1238
|
-
const firstLine = firstLineResult.value.trim();
|
|
1239
|
-
// Check if the first line is a single character short name
|
|
1240
|
-
const parsedIntent = xtabPromptOptions.EditIntent.fromShortName(firstLine);
|
|
1241
|
-
if (parsedIntent !== undefined) {
|
|
1242
|
-
editIntent = parsedIntent;
|
|
1243
|
-
tracer.trace(`Parsed edit_intent short name from first line: "${firstLine}" -> ${editIntent}`);
|
|
1244
|
-
// Create a new stream with the remaining lines (excluding the short name line)
|
|
1245
|
-
const remainingLinesStream = (async function* () {
|
|
1246
|
-
let next = await linesIter.next();
|
|
1247
|
-
while (!next.done) {
|
|
1248
|
-
yield next.value;
|
|
1249
|
-
next = await linesIter.next();
|
|
1250
|
-
}
|
|
1251
|
-
})();
|
|
1252
|
-
return { editIntent, remainingLinesStream, parseError };
|
|
1275
|
+
async function* linesWithIntermediateEditDivergenceCheck(cleanedLinesStream, cursorOriginalLinesOffset, request, editWindowLineRange, editWindowLines, fetchCts, { tracer }, setLineDiverged, mode) {
|
|
1276
|
+
const intermediateEdit = request.intermediateUserEdit;
|
|
1277
|
+
if (!intermediateEdit || intermediateEdit.isEmpty()) {
|
|
1278
|
+
yield* cleanedLinesStream;
|
|
1279
|
+
return;
|
|
1253
1280
|
}
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
const
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1281
|
+
const transformer = request.documentBeforeEdits.getTransformer();
|
|
1282
|
+
// Precompute the post-edit document once to avoid O(lines * docSize) in EditWindow mode.
|
|
1283
|
+
const currentDoc = intermediateEdit.apply(transformer.text);
|
|
1284
|
+
const currentTransformer = new positionToOffset_1.PositionOffsetTransformer(currentDoc);
|
|
1285
|
+
const precomputed = { currentDoc, currentTransformer };
|
|
1286
|
+
const shouldCheckLine = (lineIdx) => {
|
|
1287
|
+
if (lineIdx >= editWindowLines.length) {
|
|
1288
|
+
return false;
|
|
1289
|
+
}
|
|
1290
|
+
switch (mode) {
|
|
1291
|
+
case xtabPromptOptions_1.EarlyDivergenceCancellationMode.Cursor:
|
|
1292
|
+
return lineIdx === cursorOriginalLinesOffset;
|
|
1293
|
+
case xtabPromptOptions_1.EarlyDivergenceCancellationMode.EditWindow:
|
|
1294
|
+
return true;
|
|
1265
1295
|
}
|
|
1266
|
-
}
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
return { editIntent, remainingLinesStream, parseError };
|
|
1285
|
-
}
|
|
1286
|
-
const firstLine = firstLineResult.value;
|
|
1287
|
-
// Check if the first line contains the complete edit_intent tag
|
|
1288
|
-
const startIdx = firstLine.indexOf(EDIT_INTENT_START_TAG);
|
|
1289
|
-
const endIdx = firstLine.indexOf(EDIT_INTENT_END_TAG);
|
|
1290
|
-
if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
|
|
1291
|
-
// Found complete tag on first line
|
|
1292
|
-
const intentValue = firstLine.substring(startIdx + EDIT_INTENT_START_TAG.length, endIdx).trim().toLowerCase();
|
|
1293
|
-
// Check if it's a known intent value
|
|
1294
|
-
const knownIntentValues = ['no_edit', 'low', 'medium', 'high'];
|
|
1295
|
-
if (!knownIntentValues.includes(intentValue)) {
|
|
1296
|
-
parseError = `unknownIntentValue:${intentValue}`;
|
|
1297
|
-
tracer.warn(`Unknown edit_intent value: "${intentValue}", defaulting to High`);
|
|
1298
|
-
}
|
|
1299
|
-
editIntent = xtabPromptOptions.EditIntent.fromString(intentValue);
|
|
1300
|
-
tracer.trace(`Parsed edit_intent from first line: "${intentValue}" -> ${editIntent}`);
|
|
1301
|
-
// Calculate remaining content after the end tag on the first line
|
|
1302
|
-
const afterEndTag = firstLine.substring(endIdx + EDIT_INTENT_END_TAG.length);
|
|
1303
|
-
// Create a new stream that first yields remaining content from first line, then continues
|
|
1304
|
-
const remainingLinesStream = (async function* () {
|
|
1305
|
-
// Only yield remaining content from first line if non-empty
|
|
1306
|
-
if (afterEndTag.trim() !== '') {
|
|
1307
|
-
yield afterEndTag;
|
|
1308
|
-
}
|
|
1309
|
-
// Continue with rest of the stream
|
|
1310
|
-
let next = await linesIter.next();
|
|
1311
|
-
while (!next.done) {
|
|
1312
|
-
yield next.value;
|
|
1313
|
-
next = await linesIter.next();
|
|
1314
|
-
}
|
|
1315
|
-
})();
|
|
1316
|
-
return { editIntent, remainingLinesStream, parseError };
|
|
1317
|
-
}
|
|
1318
|
-
// Determine the parse error type
|
|
1319
|
-
if (startIdx !== -1 && endIdx === -1) {
|
|
1320
|
-
// Start tag found but no end tag - malformed (possibly split across lines)
|
|
1321
|
-
parseError = 'malformedTag:startWithoutEnd';
|
|
1322
|
-
}
|
|
1323
|
-
else if (startIdx === -1 && endIdx !== -1) {
|
|
1324
|
-
// End tag found but no start tag - malformed
|
|
1325
|
-
parseError = 'malformedTag:endWithoutStart';
|
|
1326
|
-
}
|
|
1327
|
-
else {
|
|
1328
|
-
// No tag found at all
|
|
1329
|
-
parseError = 'noTagFound';
|
|
1330
|
-
}
|
|
1331
|
-
tracer.warn(`Edit intent parse error: ${parseError} (using Xtab275EditIntent prompting strategy). ` +
|
|
1332
|
-
`Defaulting to High (always show). First line was: "${firstLine.substring(0, 100)}..."`);
|
|
1333
|
-
// Return the first line plus the rest of the stream
|
|
1334
|
-
const remainingLinesStream = (async function* () {
|
|
1335
|
-
yield firstLine;
|
|
1336
|
-
let next = await linesIter.next();
|
|
1337
|
-
while (!next.done) {
|
|
1338
|
-
yield next.value;
|
|
1339
|
-
next = await linesIter.next();
|
|
1340
|
-
}
|
|
1341
|
-
})();
|
|
1342
|
-
return { editIntent, remainingLinesStream, parseError };
|
|
1343
|
-
}
|
|
1344
|
-
/**
|
|
1345
|
-
* Finds the range of lines containing merge conflict markers within a specified edit window.
|
|
1346
|
-
*
|
|
1347
|
-
* @param lines - Array of strings representing the lines of text to search through
|
|
1348
|
-
* @param editWindowRange - The range within which to search for merge conflict markers
|
|
1349
|
-
* @param maxMergeConflictLines - Maximum number of lines to search for conflict markers
|
|
1350
|
-
* @returns An OffsetRange object representing the start and end of the conflict markers, or undefined if not found
|
|
1351
|
-
*/
|
|
1352
|
-
function findMergeConflictMarkersRange(lines, editWindowRange, maxMergeConflictLines) {
|
|
1353
|
-
for (let i = editWindowRange.start; i < Math.min(lines.length, editWindowRange.endExclusive); ++i) {
|
|
1354
|
-
if (!lines[i].startsWith('<<<<<<<')) {
|
|
1355
|
-
continue;
|
|
1356
|
-
}
|
|
1357
|
-
// found start of merge conflict markers -- now find the end
|
|
1358
|
-
for (let j = i + 1; j < lines.length && (j - i) < maxMergeConflictLines; ++j) {
|
|
1359
|
-
if (lines[j].startsWith('>>>>>>>')) {
|
|
1360
|
-
return new offsetRange_1.OffsetRange(i, j + 1 /* because endExclusive */);
|
|
1296
|
+
};
|
|
1297
|
+
let lineIdx = 0;
|
|
1298
|
+
for await (const line of cleanedLinesStream) {
|
|
1299
|
+
if (shouldCheckLine(lineIdx)) {
|
|
1300
|
+
const docLineIdx = editWindowLineRange.start + lineIdx;
|
|
1301
|
+
const currentLine = (0, cursorLineDivergence_1.getCurrentLine)(transformer, docLineIdx, intermediateEdit, precomputed);
|
|
1302
|
+
if (currentLine !== undefined) {
|
|
1303
|
+
const originalLine = editWindowLines[lineIdx];
|
|
1304
|
+
if (currentLine !== originalLine // user changed this line
|
|
1305
|
+
&& !(0, cursorLineDivergence_1.isModelLineCompatible)(originalLine, currentLine, line) // model's line isn't compatible with user's typing
|
|
1306
|
+
) {
|
|
1307
|
+
setLineDiverged(true);
|
|
1308
|
+
tracer.trace(`Line ${lineIdx} DIVERGED (mode=${mode}): model="${line}" current="${currentLine}"`);
|
|
1309
|
+
// Cancel our local fetch token so the HTTP request is
|
|
1310
|
+
// aborted immediately. We own this token, so this is safe.
|
|
1311
|
+
fetchCts.cancel();
|
|
1312
|
+
return;
|
|
1313
|
+
}
|
|
1361
1314
|
}
|
|
1362
1315
|
}
|
|
1316
|
+
yield line;
|
|
1317
|
+
lineIdx++;
|
|
1363
1318
|
}
|
|
1364
|
-
return undefined;
|
|
1365
1319
|
}
|
|
1366
1320
|
//# sourceMappingURL=xtabProvider.js.map
|