@vscode/chat-lib 0.4.0 → 0.4.1-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/byok/node/openAIEndpoint.d.ts +1 -6
- package/dist/src/_internal/extension/byok/node/openAIEndpoint.d.ts.map +1 -1
- package/dist/src/_internal/extension/byok/node/openAIEndpoint.js +9 -20
- package/dist/src/_internal/extension/byok/node/openAIEndpoint.js.map +1 -1
- package/dist/src/_internal/extension/common/constants.d.ts +0 -1
- package/dist/src/_internal/extension/common/constants.d.ts.map +1 -1
- package/dist/src/_internal/extension/common/constants.js +2 -1
- 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 +4 -2
- 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 +38 -5
- 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/ghostText/ghostText.d.ts +0 -1
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/ghostText/ghostText.d.ts.map +1 -1
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/ghostText/ghostText.js +17 -36
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/ghostText/ghostText.js.map +1 -1
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/openai/fetch.d.ts +1 -1
- 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 +205 -122
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/openai/fetch.js.map +1 -1
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/prompt/components/currentFile.d.ts.map +1 -1
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/prompt/components/currentFile.js +15 -7
- package/dist/src/_internal/extension/completions-core/vscode-node/lib/src/prompt/components/currentFile.js.map +1 -1
- package/dist/src/_internal/extension/inlineEdits/common/userInteractionMonitor.d.ts +52 -8
- package/dist/src/_internal/extension/inlineEdits/common/userInteractionMonitor.d.ts.map +1 -1
- package/dist/src/_internal/extension/inlineEdits/common/userInteractionMonitor.js +208 -41
- package/dist/src/_internal/extension/inlineEdits/common/userInteractionMonitor.js.map +1 -1
- package/dist/src/_internal/extension/inlineEdits/node/nesConfigs.d.ts +1 -0
- package/dist/src/_internal/extension/inlineEdits/node/nesConfigs.d.ts.map +1 -1
- package/dist/src/_internal/extension/inlineEdits/node/nextEditCache.d.ts +14 -4
- package/dist/src/_internal/extension/inlineEdits/node/nextEditCache.d.ts.map +1 -1
- package/dist/src/_internal/extension/inlineEdits/node/nextEditCache.js +46 -30
- package/dist/src/_internal/extension/inlineEdits/node/nextEditCache.js.map +1 -1
- package/dist/src/_internal/extension/inlineEdits/node/nextEditProvider.d.ts +24 -3
- package/dist/src/_internal/extension/inlineEdits/node/nextEditProvider.d.ts.map +1 -1
- package/dist/src/_internal/extension/inlineEdits/node/nextEditProvider.js +471 -128
- package/dist/src/_internal/extension/inlineEdits/node/nextEditProvider.js.map +1 -1
- package/dist/src/_internal/extension/inlineEdits/node/nextEditProviderTelemetry.d.ts.map +1 -1
- package/dist/src/_internal/extension/inlineEdits/node/nextEditProviderTelemetry.js +8 -2
- package/dist/src/_internal/extension/inlineEdits/node/nextEditProviderTelemetry.js.map +1 -1
- package/dist/src/_internal/extension/inlineEdits/node/nextEditResult.d.ts +0 -4
- package/dist/src/_internal/extension/inlineEdits/node/nextEditResult.d.ts.map +1 -1
- package/dist/src/_internal/extension/inlineEdits/node/nextEditResult.js.map +1 -1
- package/dist/src/_internal/extension/power/common/powerService.d.ts +22 -0
- package/dist/src/_internal/extension/power/common/powerService.d.ts.map +1 -0
- package/dist/src/_internal/extension/power/common/powerService.js +20 -0
- package/dist/src/_internal/extension/power/common/powerService.js.map +1 -0
- package/dist/src/_internal/extension/prompt/node/chatMLFetcher.d.ts +6 -2
- package/dist/src/_internal/extension/prompt/node/chatMLFetcher.d.ts.map +1 -1
- package/dist/src/_internal/extension/prompt/node/chatMLFetcher.js +30 -6
- package/dist/src/_internal/extension/prompt/node/chatMLFetcher.js.map +1 -1
- package/dist/src/_internal/extension/xtab/common/diffHistoryForPrompt.d.ts +6 -0
- package/dist/src/_internal/extension/xtab/common/diffHistoryForPrompt.d.ts.map +1 -0
- package/dist/src/_internal/extension/xtab/common/diffHistoryForPrompt.js +89 -0
- package/dist/src/_internal/extension/xtab/common/diffHistoryForPrompt.js.map +1 -0
- package/dist/src/_internal/extension/xtab/common/inlineSuggestion.d.ts +15 -0
- package/dist/src/_internal/extension/xtab/common/inlineSuggestion.d.ts.map +1 -0
- package/dist/src/_internal/extension/xtab/common/inlineSuggestion.js +43 -0
- package/dist/src/_internal/extension/xtab/common/inlineSuggestion.js.map +1 -0
- package/dist/src/_internal/extension/xtab/common/lintErrors.d.ts +4 -4
- package/dist/src/_internal/extension/xtab/common/lintErrors.d.ts.map +1 -1
- package/dist/src/_internal/extension/xtab/common/lintErrors.js +70 -26
- package/dist/src/_internal/extension/xtab/common/lintErrors.js.map +1 -1
- package/dist/src/_internal/extension/xtab/common/promptCrafting.d.ts +13022 -364
- package/dist/src/_internal/extension/xtab/common/promptCrafting.d.ts.map +1 -1
- package/dist/src/_internal/extension/xtab/common/promptCrafting.js +14 -233
- package/dist/src/_internal/extension/xtab/common/promptCrafting.js.map +1 -1
- package/dist/src/_internal/extension/xtab/common/promptCraftingUtils.d.ts +4 -0
- package/dist/src/_internal/extension/xtab/common/promptCraftingUtils.d.ts.map +1 -0
- package/dist/src/_internal/extension/xtab/common/promptCraftingUtils.js +22 -0
- package/dist/src/_internal/extension/xtab/common/promptCraftingUtils.js.map +1 -0
- package/dist/src/_internal/extension/xtab/common/recentFilesForPrompt.d.ts +41 -0
- package/dist/src/_internal/extension/xtab/common/recentFilesForPrompt.d.ts.map +1 -0
- package/dist/src/_internal/extension/xtab/common/recentFilesForPrompt.js +375 -0
- package/dist/src/_internal/extension/xtab/common/recentFilesForPrompt.js.map +1 -0
- package/dist/src/_internal/extension/xtab/common/terminalOutput.d.ts +20 -0
- package/dist/src/_internal/extension/xtab/common/terminalOutput.d.ts.map +1 -0
- package/dist/src/_internal/extension/xtab/common/terminalOutput.js +105 -0
- package/dist/src/_internal/extension/xtab/common/terminalOutput.js.map +1 -0
- package/dist/src/_internal/extension/xtab/node/xtabCustomDiffPatchResponseHandler.d.ts +2 -3
- package/dist/src/_internal/extension/xtab/node/xtabCustomDiffPatchResponseHandler.d.ts.map +1 -1
- package/dist/src/_internal/extension/xtab/node/xtabCustomDiffPatchResponseHandler.js +2 -1
- package/dist/src/_internal/extension/xtab/node/xtabCustomDiffPatchResponseHandler.js.map +1 -1
- package/dist/src/_internal/extension/xtab/node/xtabEndpoint.d.ts.map +1 -1
- package/dist/src/_internal/extension/xtab/node/xtabEndpoint.js +1 -1
- package/dist/src/_internal/extension/xtab/node/xtabEndpoint.js.map +1 -1
- package/dist/src/_internal/extension/xtab/node/xtabNextCursorPredictor.d.ts.map +1 -1
- package/dist/src/_internal/extension/xtab/node/xtabNextCursorPredictor.js +2 -1
- package/dist/src/_internal/extension/xtab/node/xtabNextCursorPredictor.js.map +1 -1
- package/dist/src/_internal/extension/xtab/node/xtabProvider.d.ts +52 -9
- package/dist/src/_internal/extension/xtab/node/xtabProvider.d.ts.map +1 -1
- package/dist/src/_internal/extension/xtab/node/xtabProvider.js +370 -158
- package/dist/src/_internal/extension/xtab/node/xtabProvider.js.map +1 -1
- package/dist/src/_internal/extension/xtab/node/xtabUtils.d.ts +1 -7
- package/dist/src/_internal/extension/xtab/node/xtabUtils.d.ts.map +1 -1
- package/dist/src/_internal/extension/xtab/node/xtabUtils.js +21 -40
- package/dist/src/_internal/extension/xtab/node/xtabUtils.js.map +1 -1
- package/dist/src/_internal/platform/chat/common/commonTypes.d.ts +2 -2
- package/dist/src/_internal/platform/chat/common/commonTypes.d.ts.map +1 -1
- package/dist/src/_internal/platform/chat/common/commonTypes.js +8 -8
- package/dist/src/_internal/platform/chat/common/commonTypes.js.map +1 -1
- package/dist/src/_internal/platform/configuration/common/configurationService.d.ts +40 -5
- package/dist/src/_internal/platform/configuration/common/configurationService.d.ts.map +1 -1
- package/dist/src/_internal/platform/configuration/common/configurationService.js +42 -9
- package/dist/src/_internal/platform/configuration/common/configurationService.js.map +1 -1
- package/dist/src/_internal/platform/endpoint/common/chatModelCapabilities.d.ts +1 -1
- package/dist/src/_internal/platform/endpoint/common/chatModelCapabilities.d.ts.map +1 -1
- package/dist/src/_internal/platform/endpoint/common/chatModelCapabilities.js +5 -10
- package/dist/src/_internal/platform/endpoint/common/chatModelCapabilities.js.map +1 -1
- package/dist/src/_internal/platform/endpoint/common/compactionDataContainer.d.ts +17 -0
- package/dist/src/_internal/platform/endpoint/common/compactionDataContainer.d.ts.map +1 -0
- package/dist/src/_internal/platform/endpoint/common/compactionDataContainer.js +37 -0
- package/dist/src/_internal/platform/endpoint/common/compactionDataContainer.js.map +1 -0
- package/dist/src/_internal/platform/endpoint/common/endpointProvider.d.ts +9 -5
- 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/node/autoChatEndpoint.js +1 -1
- package/dist/src/_internal/platform/endpoint/node/autoChatEndpoint.js.map +1 -1
- package/dist/src/_internal/platform/endpoint/node/chatEndpoint.d.ts +4 -11
- package/dist/src/_internal/platform/endpoint/node/chatEndpoint.d.ts.map +1 -1
- package/dist/src/_internal/platform/endpoint/node/chatEndpoint.js +14 -53
- package/dist/src/_internal/platform/endpoint/node/chatEndpoint.js.map +1 -1
- package/dist/src/_internal/platform/endpoint/node/copilotChatEndpoint.d.ts.map +1 -1
- package/dist/src/_internal/platform/endpoint/node/copilotChatEndpoint.js +1 -1
- package/dist/src/_internal/platform/endpoint/node/copilotChatEndpoint.js.map +1 -1
- package/dist/src/_internal/platform/endpoint/node/messagesApi.d.ts.map +1 -1
- package/dist/src/_internal/platform/endpoint/node/messagesApi.js +41 -23
- package/dist/src/_internal/platform/endpoint/node/messagesApi.js.map +1 -1
- package/dist/src/_internal/platform/endpoint/node/responsesApi.d.ts.map +1 -1
- package/dist/src/_internal/platform/endpoint/node/responsesApi.js +58 -2
- package/dist/src/_internal/platform/endpoint/node/responsesApi.js.map +1 -1
- package/dist/src/_internal/platform/env/common/envService.d.ts +6 -0
- package/dist/src/_internal/platform/env/common/envService.d.ts.map +1 -1
- package/dist/src/_internal/platform/env/common/envService.js.map +1 -1
- package/dist/src/_internal/platform/env/common/nullEnvService.d.ts +3 -0
- package/dist/src/_internal/platform/env/common/nullEnvService.d.ts.map +1 -1
- package/dist/src/_internal/platform/env/common/nullEnvService.js +4 -0
- package/dist/src/_internal/platform/env/common/nullEnvService.js.map +1 -1
- package/dist/src/_internal/platform/github/common/githubAPI.d.ts +1 -1
- package/dist/src/_internal/platform/github/common/githubAPI.d.ts.map +1 -1
- package/dist/src/_internal/platform/github/common/githubAPI.js +4 -2
- package/dist/src/_internal/platform/github/common/githubAPI.js.map +1 -1
- package/dist/src/_internal/platform/github/common/githubService.d.ts +2 -0
- package/dist/src/_internal/platform/github/common/githubService.d.ts.map +1 -1
- package/dist/src/_internal/platform/github/common/githubService.js +3 -3
- package/dist/src/_internal/platform/github/common/githubService.js.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/dataTypes/xtabHistoryOptions.d.ts +9 -0
- package/dist/src/_internal/platform/inlineEdits/common/dataTypes/xtabHistoryOptions.d.ts.map +1 -0
- package/dist/src/_internal/platform/inlineEdits/common/dataTypes/xtabHistoryOptions.js +18 -0
- package/dist/src/_internal/platform/inlineEdits/common/dataTypes/xtabHistoryOptions.js.map +1 -0
- package/dist/src/_internal/platform/inlineEdits/common/dataTypes/xtabPromptOptions.d.ts +103 -2
- package/dist/src/_internal/platform/inlineEdits/common/dataTypes/xtabPromptOptions.d.ts.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/dataTypes/xtabPromptOptions.js +231 -1
- package/dist/src/_internal/platform/inlineEdits/common/dataTypes/xtabPromptOptions.js.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/inlineEditLogContext.d.ts +11 -5
- package/dist/src/_internal/platform/inlineEdits/common/inlineEditLogContext.d.ts.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/inlineEditLogContext.js +33 -18
- package/dist/src/_internal/platform/inlineEdits/common/inlineEditLogContext.js.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/inlineEditsModelService.d.ts +2 -0
- package/dist/src/_internal/platform/inlineEdits/common/inlineEditsModelService.d.ts.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/inlineEditsModelService.js +4 -0
- package/dist/src/_internal/platform/inlineEdits/common/inlineEditsModelService.js.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/responseProcessor.d.ts +1 -2
- package/dist/src/_internal/platform/inlineEdits/common/responseProcessor.d.ts.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/responseProcessor.js +13 -0
- package/dist/src/_internal/platform/inlineEdits/common/responseProcessor.js.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/statelessNextEditProvider.d.ts +37 -10
- package/dist/src/_internal/platform/inlineEdits/common/statelessNextEditProvider.d.ts.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/statelessNextEditProvider.js +43 -6
- package/dist/src/_internal/platform/inlineEdits/common/statelessNextEditProvider.js.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/workspaceEditTracker/nesXtabHistoryTracker.d.ts +41 -2
- package/dist/src/_internal/platform/inlineEdits/common/workspaceEditTracker/nesXtabHistoryTracker.d.ts.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/common/workspaceEditTracker/nesXtabHistoryTracker.js +90 -8
- package/dist/src/_internal/platform/inlineEdits/common/workspaceEditTracker/nesXtabHistoryTracker.js.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/node/inlineEditsModelService.d.ts +9 -2
- package/dist/src/_internal/platform/inlineEdits/node/inlineEditsModelService.d.ts.map +1 -1
- package/dist/src/_internal/platform/inlineEdits/node/inlineEditsModelService.js +65 -54
- package/dist/src/_internal/platform/inlineEdits/node/inlineEditsModelService.js.map +1 -1
- package/dist/src/_internal/platform/log/common/logService.d.ts +30 -0
- package/dist/src/_internal/platform/log/common/logService.d.ts.map +1 -1
- package/dist/src/_internal/platform/log/common/logService.js.map +1 -1
- package/dist/src/_internal/platform/nesFetch/node/completionsFetchServiceImpl.d.ts +5 -1
- package/dist/src/_internal/platform/nesFetch/node/completionsFetchServiceImpl.d.ts.map +1 -1
- package/dist/src/_internal/platform/nesFetch/node/completionsFetchServiceImpl.js +121 -6
- package/dist/src/_internal/platform/nesFetch/node/completionsFetchServiceImpl.js.map +1 -1
- package/dist/src/_internal/platform/nesFetch/node/streamTransformer.d.ts +1 -4
- package/dist/src/_internal/platform/nesFetch/node/streamTransformer.d.ts.map +1 -1
- package/dist/src/_internal/platform/nesFetch/node/streamTransformer.js +1 -21
- package/dist/src/_internal/platform/nesFetch/node/streamTransformer.js.map +1 -1
- package/dist/src/_internal/platform/networking/common/anthropic.d.ts +4 -1
- package/dist/src/_internal/platform/networking/common/anthropic.d.ts.map +1 -1
- package/dist/src/_internal/platform/networking/common/anthropic.js +17 -4
- package/dist/src/_internal/platform/networking/common/anthropic.js.map +1 -1
- package/dist/src/_internal/platform/networking/common/fetch.d.ts +4 -2
- package/dist/src/_internal/platform/networking/common/fetch.d.ts.map +1 -1
- package/dist/src/_internal/platform/networking/common/fetch.js +9 -0
- 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 +14 -12
- package/dist/src/_internal/platform/networking/common/networking.d.ts.map +1 -1
- package/dist/src/_internal/platform/networking/common/networking.js +1 -0
- package/dist/src/_internal/platform/networking/common/networking.js.map +1 -1
- package/dist/src/_internal/platform/networking/common/openai.d.ts +11 -0
- package/dist/src/_internal/platform/networking/common/openai.d.ts.map +1 -1
- package/dist/src/_internal/platform/networking/common/openai.js +3 -1
- package/dist/src/_internal/platform/networking/common/openai.js.map +1 -1
- package/dist/src/_internal/platform/requestLogger/common/capturingToken.d.ts +35 -1
- package/dist/src/_internal/platform/requestLogger/common/capturingToken.d.ts.map +1 -1
- package/dist/src/_internal/platform/requestLogger/common/capturingToken.js +21 -1
- package/dist/src/_internal/platform/requestLogger/common/capturingToken.js.map +1 -1
- package/dist/src/_internal/platform/requestLogger/node/requestLogger.d.ts +35 -0
- package/dist/src/_internal/platform/requestLogger/node/requestLogger.d.ts.map +1 -1
- package/dist/src/_internal/platform/requestLogger/node/requestLogger.js +54 -1
- package/dist/src/_internal/platform/requestLogger/node/requestLogger.js.map +1 -1
- package/dist/src/_internal/platform/telemetry/common/telemetry.d.ts +2 -0
- package/dist/src/_internal/platform/telemetry/common/telemetry.d.ts.map +1 -1
- package/dist/src/_internal/platform/telemetry/common/telemetry.js +1 -0
- package/dist/src/_internal/platform/telemetry/common/telemetry.js.map +1 -1
- package/dist/src/_internal/platform/telemetry/common/telemetryData.d.ts.map +1 -1
- package/dist/src/_internal/platform/telemetry/common/telemetryData.js +3 -0
- package/dist/src/_internal/platform/telemetry/common/telemetryData.js.map +1 -1
- package/dist/src/_internal/platform/terminal/common/terminalService.d.ts +111 -0
- package/dist/src/_internal/platform/terminal/common/terminalService.d.ts.map +1 -0
- package/dist/src/_internal/platform/terminal/common/terminalService.js +83 -0
- package/dist/src/_internal/platform/terminal/common/terminalService.js.map +1 -0
- package/dist/src/_internal/util/common/arrays.d.ts +5 -0
- package/dist/src/_internal/util/common/arrays.d.ts.map +1 -1
- package/dist/src/_internal/util/common/arrays.js +10 -0
- package/dist/src/_internal/util/common/arrays.js.map +1 -1
- package/dist/src/_internal/util/common/asyncIterableUtils.d.ts +17 -0
- package/dist/src/_internal/util/common/asyncIterableUtils.d.ts.map +1 -0
- package/dist/src/_internal/util/common/asyncIterableUtils.js +94 -0
- package/dist/src/_internal/util/common/asyncIterableUtils.js.map +1 -0
- package/dist/src/_internal/util/common/result.d.ts +34 -10
- package/dist/src/_internal/util/common/result.d.ts.map +1 -1
- package/dist/src/_internal/util/common/result.js +91 -2
- package/dist/src/_internal/util/common/result.js.map +1 -1
- package/dist/src/_internal/util/common/test/shims/chatTypes.d.ts +15 -3
- package/dist/src/_internal/util/common/test/shims/chatTypes.d.ts.map +1 -1
- package/dist/src/_internal/util/common/test/shims/chatTypes.js +26 -4
- package/dist/src/_internal/util/common/test/shims/chatTypes.js.map +1 -1
- package/dist/src/_internal/util/common/test/shims/themes.d.ts +13 -0
- package/dist/src/_internal/util/common/test/shims/themes.d.ts.map +1 -0
- package/dist/src/_internal/util/common/test/shims/themes.js +27 -0
- package/dist/src/_internal/util/common/test/shims/themes.js.map +1 -0
- package/dist/src/_internal/util/common/test/shims/vscodeTypesShim.d.ts.map +1 -1
- package/dist/src/_internal/util/common/test/shims/vscodeTypesShim.js +4 -1
- package/dist/src/_internal/util/common/test/shims/vscodeTypesShim.js.map +1 -1
- package/dist/src/_internal/util/vs/base/common/codicons.d.ts +2 -0
- package/dist/src/_internal/util/vs/base/common/codicons.d.ts.map +1 -1
- package/dist/src/_internal/util/vs/base/common/codiconsLibrary.d.ts +2 -0
- package/dist/src/_internal/util/vs/base/common/codiconsLibrary.d.ts.map +1 -1
- package/dist/src/_internal/util/vs/base/common/codiconsLibrary.js +2 -0
- package/dist/src/_internal/util/vs/base/common/codiconsLibrary.js.map +1 -1
- package/dist/src/_internal/util/vs/base/common/mime.d.ts.map +1 -1
- package/dist/src/_internal/util/vs/base/common/mime.js +7 -5
- package/dist/src/_internal/util/vs/base/common/mime.js.map +1 -1
- package/dist/src/_internal/util/vs/editor/common/core/ranges/offsetRange.d.ts +4 -0
- package/dist/src/_internal/util/vs/editor/common/core/ranges/offsetRange.d.ts.map +1 -1
- package/dist/src/_internal/util/vs/editor/common/core/ranges/offsetRange.js +4 -0
- package/dist/src/_internal/util/vs/editor/common/core/ranges/offsetRange.js.map +1 -1
- package/dist/src/_internal/vscodeTypes.d.ts +2 -0
- package/dist/src/_internal/vscodeTypes.d.ts.map +1 -1
- package/dist/src/_internal/vscodeTypes.js +4 -2
- package/dist/src/_internal/vscodeTypes.js.map +1 -1
- package/dist/src/main.d.ts +4 -1
- package/dist/src/main.d.ts.map +1 -1
- package/dist/src/main.js +10 -1
- package/dist/src/main.js.map +1 -1
- package/dist/src/package.json +445 -193
- package/package.json +2 -2
|
@@ -47,12 +47,16 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
47
47
|
};
|
|
48
48
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
49
|
exports.NextEditFetchRequest = exports.NextEditProvider = void 0;
|
|
50
|
+
const path_1 = require("path");
|
|
50
51
|
const configurationService_1 = require("../../../platform/configuration/common/configurationService");
|
|
51
52
|
const edit_1 = require("../../../platform/inlineEdits/common/dataTypes/edit");
|
|
52
53
|
const rootedLineEdit_1 = require("../../../platform/inlineEdits/common/dataTypes/rootedLineEdit");
|
|
54
|
+
const inlineEditLogContext_1 = require("../../../platform/inlineEdits/common/inlineEditLogContext");
|
|
53
55
|
const statelessNextEditProvider_1 = require("../../../platform/inlineEdits/common/statelessNextEditProvider");
|
|
54
56
|
const observable_1 = require("../../../platform/inlineEdits/common/utils/observable");
|
|
55
57
|
const logService_1 = require("../../../platform/log/common/logService");
|
|
58
|
+
const capturingToken_1 = require("../../../platform/requestLogger/common/capturingToken");
|
|
59
|
+
const requestLogger_1 = require("../../../platform/requestLogger/node/requestLogger");
|
|
56
60
|
const snippyService_1 = require("../../../platform/snippy/common/snippyService");
|
|
57
61
|
const nullExperimentationService_1 = require("../../../platform/telemetry/common/nullExperimentationService");
|
|
58
62
|
const errors = __importStar(require("../../../util/common/errors"));
|
|
@@ -68,11 +72,40 @@ const types_1 = require("../../../util/vs/base/common/types");
|
|
|
68
72
|
const uuid_1 = require("../../../util/vs/base/common/uuid");
|
|
69
73
|
const lineEdit_1 = require("../../../util/vs/editor/common/core/edits/lineEdit");
|
|
70
74
|
const stringEdit_1 = require("../../../util/vs/editor/common/core/edits/stringEdit");
|
|
75
|
+
const position_1 = require("../../../util/vs/editor/common/core/position");
|
|
71
76
|
const offsetRange_1 = require("../../../util/vs/editor/common/core/ranges/offsetRange");
|
|
77
|
+
const abstractText_1 = require("../../../util/vs/editor/common/core/text/abstractText");
|
|
72
78
|
const editRebase_1 = require("../common/editRebase");
|
|
73
79
|
const rejectionCollector_1 = require("../common/rejectionCollector");
|
|
74
80
|
const nextEditCache_1 = require("./nextEditCache");
|
|
75
81
|
const nextEditResult_1 = require("./nextEditResult");
|
|
82
|
+
/**
|
|
83
|
+
* Computes a reduced window range that encompasses both the original window (shrunk by one line
|
|
84
|
+
* on each end) and the full line where the cursor is located.
|
|
85
|
+
*
|
|
86
|
+
* This ensures the cache invalidation window always includes the cursor's line while trimming
|
|
87
|
+
* the edges of the original window.
|
|
88
|
+
*/
|
|
89
|
+
function computeReducedWindow(window, activeDocSelection, documentBeforeEdits) {
|
|
90
|
+
if (!activeDocSelection) {
|
|
91
|
+
return window;
|
|
92
|
+
}
|
|
93
|
+
const cursorOffset = activeDocSelection.endExclusive;
|
|
94
|
+
const t = documentBeforeEdits.getTransformer();
|
|
95
|
+
const cursorPosition = t.getPosition(cursorOffset);
|
|
96
|
+
const lineOffset = t.getOffset(cursorPosition.with(undefined, 1));
|
|
97
|
+
const lineEndOffset = t.getOffset(cursorPosition.with(undefined, t.getLineLength(cursorPosition.lineNumber) + 1));
|
|
98
|
+
const reducedOffset = t.getOffset(t.getPosition(window.start).delta(1));
|
|
99
|
+
const reducedEndPosition = t.getPosition(window.endExclusive).delta(-2);
|
|
100
|
+
const reducedEndOffset = t.getOffset(reducedEndPosition.column > 1 ? reducedEndPosition.with(undefined, t.getLineLength(reducedEndPosition.lineNumber) + 1) : reducedEndPosition);
|
|
101
|
+
return new offsetRange_1.OffsetRange(Math.min(reducedOffset, lineOffset), Math.max(reducedEndOffset, lineEndOffset));
|
|
102
|
+
}
|
|
103
|
+
function convertLineEditToEdit(nextLineEdit, projectedDocuments, docId) {
|
|
104
|
+
const doc = projectedDocuments.find(d => d.nextEditDoc.id === docId);
|
|
105
|
+
const rootedLineEdit = new rootedLineEdit_1.RootedLineEdit(doc.documentAfterEdits, nextLineEdit);
|
|
106
|
+
const suggestedEdit = rootedLineEdit.toEdit();
|
|
107
|
+
return suggestedEdit;
|
|
108
|
+
}
|
|
76
109
|
let NextEditProvider = class NextEditProvider extends lifecycle_1.Disposable {
|
|
77
110
|
get lastRejectionTime() {
|
|
78
111
|
return this._lastRejectionTime;
|
|
@@ -80,7 +113,7 @@ let NextEditProvider = class NextEditProvider extends lifecycle_1.Disposable {
|
|
|
80
113
|
get lastTriggerTime() {
|
|
81
114
|
return this._lastTriggerTime;
|
|
82
115
|
}
|
|
83
|
-
constructor(_workspace, _statelessNextEditProvider, _historyContextProvider, _xtabHistoryTracker, _debugRecorder, _configService, _snippyService, _logService, _expService) {
|
|
116
|
+
constructor(_workspace, _statelessNextEditProvider, _historyContextProvider, _xtabHistoryTracker, _debugRecorder, _configService, _snippyService, _logService, _expService, _requestLogger) {
|
|
84
117
|
super();
|
|
85
118
|
this._workspace = _workspace;
|
|
86
119
|
this._statelessNextEditProvider = _statelessNextEditProvider;
|
|
@@ -91,10 +124,19 @@ let NextEditProvider = class NextEditProvider extends lifecycle_1.Disposable {
|
|
|
91
124
|
this._snippyService = _snippyService;
|
|
92
125
|
this._logService = _logService;
|
|
93
126
|
this._expService = _expService;
|
|
127
|
+
this._requestLogger = _requestLogger;
|
|
94
128
|
this.ID = this._statelessNextEditProvider.ID;
|
|
95
129
|
this._rejectionCollector = this._register(new rejectionCollector_1.RejectionCollector(this._workspace, this._logService));
|
|
96
130
|
this._pendingStatelessNextEditRequest = null;
|
|
131
|
+
/**
|
|
132
|
+
* Tracks a speculative request for the post-edit document state.
|
|
133
|
+
* When a suggestion is shown, we speculatively fetch the next edit as if the user had already accepted.
|
|
134
|
+
* This allows reusing the in-flight request when the user actually accepts the suggestion.
|
|
135
|
+
*/
|
|
136
|
+
this._speculativePendingRequest = null;
|
|
97
137
|
this._lastShownTime = 0;
|
|
138
|
+
/** The requestId of the last shown suggestion. We store only the requestId (not the object) to avoid preventing garbage collection. */
|
|
139
|
+
this._lastShownSuggestionId = undefined;
|
|
98
140
|
this._lastRejectionTime = 0;
|
|
99
141
|
this._lastTriggerTime = 0;
|
|
100
142
|
this._shouldExpandEditWindow = false;
|
|
@@ -152,7 +194,7 @@ let NextEditProvider = class NextEditProvider extends lifecycle_1.Disposable {
|
|
|
152
194
|
const documentAtInvocationTime = doc.value.get();
|
|
153
195
|
const selections = doc.selection.get();
|
|
154
196
|
const nesConfigs = this.determineNesConfigs(telemetryBuilder, logContext);
|
|
155
|
-
const cachedEdit = this._nextEditCache.lookupNextEdit(docId, documentAtInvocationTime, selections
|
|
197
|
+
const cachedEdit = this._nextEditCache.lookupNextEdit(docId, documentAtInvocationTime, selections);
|
|
156
198
|
if (cachedEdit?.rejected) {
|
|
157
199
|
logger.trace('cached edit was previously rejected');
|
|
158
200
|
telemetryBuilder.setStatus('previouslyRejectedCache');
|
|
@@ -251,7 +293,7 @@ let NextEditProvider = class NextEditProvider extends lifecycle_1.Disposable {
|
|
|
251
293
|
telemetryBuilder.setStatus(`noEdit:gotCancelled`);
|
|
252
294
|
return emptyResult;
|
|
253
295
|
}
|
|
254
|
-
if (this._rejectionCollector.isRejected(targetDocumentId, edit.actualEdit) || currentDocument && this._nextEditCache.isRejectedNextEdit(targetDocumentId, currentDocument, edit.actualEdit
|
|
296
|
+
if (this._rejectionCollector.isRejected(targetDocumentId, edit.actualEdit) || currentDocument && this._nextEditCache.isRejectedNextEdit(targetDocumentId, currentDocument, edit.actualEdit)) {
|
|
255
297
|
logger.trace('edit was previously rejected');
|
|
256
298
|
telemetryBuilder.setStatus('previouslyRejected');
|
|
257
299
|
telemetryBuilder.setWasPreviouslyRejected();
|
|
@@ -260,8 +302,7 @@ let NextEditProvider = class NextEditProvider extends lifecycle_1.Disposable {
|
|
|
260
302
|
logContext.setResult(rootedLineEdit_1.RootedLineEdit.fromEdit(new edit_1.RootedEdit(documentAtInvocationTime, new stringEdit_1.StringEdit([edit.actualEdit]))));
|
|
261
303
|
(0, assert_1.assert)(currentDocument !== undefined, 'should be defined if edit is defined');
|
|
262
304
|
telemetryBuilder.setStatus('notAccepted'); // Acceptance pending.
|
|
263
|
-
const
|
|
264
|
-
const nextEditResult = new nextEditResult_1.NextEditResult(logContext.requestId, req, { edit: edit.actualEdit, isFromCursorJump: edit.isFromCursorJump, showRangePreference, documentBeforeEdits: currentDocument, targetDocumentId });
|
|
305
|
+
const nextEditResult = new nextEditResult_1.NextEditResult(logContext.requestId, req, { edit: edit.actualEdit, isFromCursorJump: edit.isFromCursorJump, documentBeforeEdits: currentDocument, targetDocumentId });
|
|
265
306
|
telemetryBuilder.setHasNextEdit(true);
|
|
266
307
|
const delay = this.computeMinimumResponseDelay({ triggerTime, isRebasedCachedEdit, isSubsequentCachedEdit, enforceCacheDelay: context.enforceCacheDelay }, logger);
|
|
267
308
|
if (delay > 0) {
|
|
@@ -278,6 +319,7 @@ let NextEditProvider = class NextEditProvider extends lifecycle_1.Disposable {
|
|
|
278
319
|
determineNesConfigs(telemetryBuilder, logContext) {
|
|
279
320
|
const nesConfigs = {
|
|
280
321
|
isAsyncCompletions: this._configService.getExperimentBasedConfig(configurationService_1.ConfigKey.TeamInternal.InlineEditsAsyncCompletions, this._expService),
|
|
322
|
+
isEagerBackupRequest: this._configService.getExperimentBasedConfig(configurationService_1.ConfigKey.TeamInternal.InlineEditsEagerBackupRequest, this._expService),
|
|
281
323
|
};
|
|
282
324
|
telemetryBuilder.setNESConfigs({ ...nesConfigs });
|
|
283
325
|
logContext.addCodeblockToLog(JSON.stringify(nesConfigs, null, '\t'));
|
|
@@ -308,21 +350,75 @@ let NextEditProvider = class NextEditProvider extends lifecycle_1.Disposable {
|
|
|
308
350
|
const selectionAtInvocationTime = doc.selection.get();
|
|
309
351
|
const logContext = req.log;
|
|
310
352
|
logContext.setRecentEdit(historyContext);
|
|
353
|
+
// Check if we can reuse the regular pending request
|
|
311
354
|
const pendingRequestStillCurrent = documentAtInvocationTime.value === this._pendingStatelessNextEditRequest?.documentBeforeEdits.value;
|
|
312
355
|
const existingNextEditRequest = (pendingRequestStillCurrent || nesConfigs.isAsyncCompletions) && !this._pendingStatelessNextEditRequest?.cancellationTokenSource.token.isCancellationRequested
|
|
313
356
|
&& this._pendingStatelessNextEditRequest || undefined;
|
|
314
|
-
if (
|
|
357
|
+
// Check if we can reuse the speculative pending request (from when a suggestion was shown)
|
|
358
|
+
const speculativeRequestMatches = this._speculativePendingRequest?.postEditContent === documentAtInvocationTime.value
|
|
359
|
+
&& !this._speculativePendingRequest.request.cancellationTokenSource.token.isCancellationRequested;
|
|
360
|
+
const speculativeRequest = speculativeRequestMatches ? this._speculativePendingRequest?.request : undefined;
|
|
361
|
+
// Prefer speculative request if it matches (it was specifically created for this post-edit state)
|
|
362
|
+
const requestToReuse = speculativeRequest ?? existingNextEditRequest;
|
|
363
|
+
if (requestToReuse) {
|
|
315
364
|
// Nice! No need to make another request, we can reuse the result from a pending request.
|
|
316
|
-
|
|
317
|
-
|
|
365
|
+
if (speculativeRequest) {
|
|
366
|
+
logger.trace(`reusing speculative pending request (opportunityId=${speculativeRequest.opportunityId}, headerRequestId=${speculativeRequest.headerRequestId})`);
|
|
367
|
+
// Clear the speculative request since we're using it
|
|
368
|
+
this._speculativePendingRequest = null;
|
|
369
|
+
}
|
|
370
|
+
const requestStillCurrent = speculativeRequest
|
|
371
|
+
? speculativeRequestMatches // For speculative, we already checked it matches
|
|
372
|
+
: pendingRequestStillCurrent;
|
|
373
|
+
if (requestStillCurrent) {
|
|
374
|
+
const nextEditResult = await this._joinNextEditRequest(requestToReuse, telemetryBuilder, logContext, cancellationToken);
|
|
318
375
|
telemetryBuilder.setStatelessNextEditTelemetry(nextEditResult.telemetry);
|
|
319
|
-
return nextEditResult.nextEdit.isError() ? nextEditResult.nextEdit :
|
|
376
|
+
return nextEditResult.nextEdit.isError() ? nextEditResult.nextEdit : requestToReuse.firstEdit.p;
|
|
377
|
+
}
|
|
378
|
+
else if (nesConfigs.isEagerBackupRequest) {
|
|
379
|
+
// The pending request is stale (document diverged). Start a backup request
|
|
380
|
+
// in parallel so that if rebase fails, we already have a head start.
|
|
381
|
+
logger.trace('starting eager backup request in parallel with rebase attempt');
|
|
382
|
+
// _executeNewNextEditRequest cancels the current _pendingStatelessNextEditRequest,
|
|
383
|
+
// but we're still trying to join+rebase requestToReuse. Temporarily clear the
|
|
384
|
+
// pending field so the stale request isn't cancelled prematurely.
|
|
385
|
+
this._pendingStatelessNextEditRequest = null;
|
|
386
|
+
const backupPromise = this._executeNewNextEditRequest(req, doc, historyContext, nesConfigs, shouldExpandEditWindow, logger, telemetryBuilder, cancellationToken);
|
|
387
|
+
const cancelBackupRequest = () => {
|
|
388
|
+
void backupPromise
|
|
389
|
+
.then(r => r.nextEditRequest.cancellationTokenSource.cancel())
|
|
390
|
+
.catch(() => undefined);
|
|
391
|
+
};
|
|
392
|
+
// Simultaneously attempt to join + rebase the stale request
|
|
393
|
+
const nextEditResult = await this._joinNextEditRequest(requestToReuse, telemetryBuilder, logContext, cancellationToken);
|
|
394
|
+
const cacheResult = await requestToReuse.firstEdit.p;
|
|
395
|
+
if (cacheResult.isOk() && cacheResult.val.edit) {
|
|
396
|
+
const rebasedCachedEdit = this._nextEditCache.tryRebaseCacheEntry(cacheResult.val, documentAtInvocationTime, selectionAtInvocationTime);
|
|
397
|
+
if (rebasedCachedEdit) {
|
|
398
|
+
logger.trace('rebase succeeded, cancelling eager backup request');
|
|
399
|
+
cancelBackupRequest();
|
|
400
|
+
telemetryBuilder.setStatelessNextEditTelemetry(nextEditResult.telemetry);
|
|
401
|
+
return result_1.Result.ok(rebasedCachedEdit);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
if (cancellationToken.isCancellationRequested) {
|
|
405
|
+
logger.trace('cancelled after rebase failed (eager backup path)');
|
|
406
|
+
cancelBackupRequest();
|
|
407
|
+
telemetryBuilder.setStatelessNextEditTelemetry(nextEditResult.telemetry);
|
|
408
|
+
return result_1.Result.error(new statelessNextEditProvider_1.NoNextEditReason.GotCancelled('afterFailedRebase'));
|
|
409
|
+
}
|
|
410
|
+
// Rebase failed — use the backup request that's already been running in parallel
|
|
411
|
+
logger.trace('rebase failed, using eager backup request');
|
|
412
|
+
const backupRes = await backupPromise;
|
|
413
|
+
telemetryBuilder.setStatelessNextEditTelemetry(backupRes.nextEditResult.telemetry);
|
|
414
|
+
return backupRes.nextEditResult.nextEdit.isError() ? backupRes.nextEditResult.nextEdit : backupRes.nextEditRequest.firstEdit.p;
|
|
320
415
|
}
|
|
321
416
|
else {
|
|
417
|
+
const nextEditResult = await this._joinNextEditRequest(requestToReuse, telemetryBuilder, logContext, cancellationToken);
|
|
322
418
|
// Needs rebasing.
|
|
323
|
-
const cacheResult = await
|
|
419
|
+
const cacheResult = await requestToReuse.firstEdit.p;
|
|
324
420
|
if (cacheResult.isOk() && cacheResult.val.edit) {
|
|
325
|
-
const rebasedCachedEdit = this._nextEditCache.tryRebaseCacheEntry(cacheResult.val, documentAtInvocationTime, selectionAtInvocationTime
|
|
421
|
+
const rebasedCachedEdit = this._nextEditCache.tryRebaseCacheEntry(cacheResult.val, documentAtInvocationTime, selectionAtInvocationTime);
|
|
326
422
|
if (rebasedCachedEdit) {
|
|
327
423
|
telemetryBuilder.setStatelessNextEditTelemetry(nextEditResult.telemetry);
|
|
328
424
|
return result_1.Result.ok(rebasedCachedEdit);
|
|
@@ -334,14 +430,14 @@ let NextEditProvider = class NextEditProvider extends lifecycle_1.Disposable {
|
|
|
334
430
|
return result_1.Result.error(new statelessNextEditProvider_1.NoNextEditReason.GotCancelled('afterFailedRebase'));
|
|
335
431
|
}
|
|
336
432
|
// Rebase failed (or result had error). Check if there is a new pending request. Otherwise continue with a new request below.
|
|
337
|
-
const
|
|
338
|
-
const existingNextEditRequest2 =
|
|
433
|
+
const pendingRequestStillCurrent2 = documentAtInvocationTime.value === this._pendingStatelessNextEditRequest?.documentBeforeEdits.value;
|
|
434
|
+
const existingNextEditRequest2 = pendingRequestStillCurrent2 && !this._pendingStatelessNextEditRequest?.cancellationTokenSource.token.isCancellationRequested
|
|
339
435
|
&& this._pendingStatelessNextEditRequest || undefined;
|
|
340
436
|
if (existingNextEditRequest2) {
|
|
341
437
|
logger.trace('reusing 2nd existing next edit request after rebase failed');
|
|
342
|
-
const
|
|
343
|
-
telemetryBuilder.setStatelessNextEditTelemetry(
|
|
344
|
-
return
|
|
438
|
+
const nextEditResult2 = await this._joinNextEditRequest(existingNextEditRequest2, telemetryBuilder, logContext, cancellationToken);
|
|
439
|
+
telemetryBuilder.setStatelessNextEditTelemetry(nextEditResult2.telemetry);
|
|
440
|
+
return nextEditResult2.nextEdit.isError() ? nextEditResult2.nextEdit : existingNextEditRequest2.firstEdit.p;
|
|
345
441
|
}
|
|
346
442
|
logger.trace('creating new next edit request after rebase failed');
|
|
347
443
|
}
|
|
@@ -354,7 +450,7 @@ let NextEditProvider = class NextEditProvider extends lifecycle_1.Disposable {
|
|
|
354
450
|
}
|
|
355
451
|
async _joinNextEditRequest(nextEditRequest, telemetryBuilder, logContext, cancellationToken) {
|
|
356
452
|
// TODO: Will the telemetry look alright in this case?
|
|
357
|
-
telemetryBuilder.setHeaderRequestId(nextEditRequest.
|
|
453
|
+
telemetryBuilder.setHeaderRequestId(nextEditRequest.headerRequestId);
|
|
358
454
|
telemetryBuilder.setIsFromCache();
|
|
359
455
|
telemetryBuilder.setRequest(nextEditRequest);
|
|
360
456
|
logContext.setRequestInput(nextEditRequest);
|
|
@@ -376,12 +472,6 @@ let NextEditProvider = class NextEditProvider extends lifecycle_1.Disposable {
|
|
|
376
472
|
const activeDocSelection = doc.selection.get()[0];
|
|
377
473
|
const projectedDocuments = historyContext.documents.map(doc => this._processDoc(doc));
|
|
378
474
|
const xtabEditHistory = this._xtabHistoryTracker.getHistory();
|
|
379
|
-
function convertLineEditToEdit(nextLineEdit, docId) {
|
|
380
|
-
const doc = projectedDocuments.find(d => d.nextEditDoc.id === docId);
|
|
381
|
-
const rootedLineEdit = new rootedLineEdit_1.RootedLineEdit(doc.documentAfterEdits, nextLineEdit);
|
|
382
|
-
const suggestedEdit = rootedLineEdit.toEdit();
|
|
383
|
-
return suggestedEdit;
|
|
384
|
-
}
|
|
385
475
|
const firstEdit = new async_1.DeferredPromise();
|
|
386
476
|
const nLinesEditWindow = (shouldExpandEditWindow
|
|
387
477
|
? this._configService.getExperimentBasedConfig(configurationService_1.ConfigKey.TeamInternal.InlineEditsAutoExpandEditWindowLines, this._expService)
|
|
@@ -420,117 +510,132 @@ let NextEditProvider = class NextEditProvider extends lifecycle_1.Disposable {
|
|
|
420
510
|
}
|
|
421
511
|
});
|
|
422
512
|
}) : undefined);
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
const { documentBeforeEdits, window } = result.err;
|
|
454
|
-
let reducedWindow = window;
|
|
455
|
-
if (activeDocSelection && window) {
|
|
456
|
-
const cursorOffset = activeDocSelection.endExclusive;
|
|
457
|
-
const t = documentBeforeEdits.getTransformer();
|
|
458
|
-
const cursorPosition = t.getPosition(cursorOffset);
|
|
459
|
-
const lineOffset = t.getOffset(cursorPosition.with(undefined, 1));
|
|
460
|
-
const lineEndOffset = t.getOffset(cursorPosition.with(undefined, t.getLineLength(cursorPosition.lineNumber) + 1));
|
|
461
|
-
const reducedOffset = t.getOffset(t.getPosition(window.start).delta(1));
|
|
462
|
-
const reducedEndPosition = t.getPosition(window.endExclusive).delta(-2);
|
|
463
|
-
const reducedEndOffset = t.getOffset(reducedEndPosition.column > 1 ? reducedEndPosition.with(undefined, t.getLineLength(reducedEndPosition.lineNumber) + 1) : reducedEndPosition);
|
|
464
|
-
reducedWindow = new offsetRange_1.OffsetRange(Math.min(reducedOffset, lineOffset), Math.max(reducedEndOffset, lineEndOffset));
|
|
465
|
-
}
|
|
466
|
-
this._nextEditCache.setNoNextEdit(curDocId, documentBeforeEdits, reducedWindow, req);
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
{
|
|
470
|
-
disp.dispose();
|
|
471
|
-
removeFromPending();
|
|
472
|
-
}
|
|
473
|
-
if (!firstEdit.isSettled) {
|
|
474
|
-
firstEdit.complete(result);
|
|
475
|
-
}
|
|
476
|
-
return;
|
|
513
|
+
const statePerDoc = new cache_1.CachedFunction((id) => {
|
|
514
|
+
const doc = projectedDocuments.find(d => d.nextEditDoc.id === id);
|
|
515
|
+
if (!doc) {
|
|
516
|
+
throw new errors_1.BugIndicatingError();
|
|
517
|
+
}
|
|
518
|
+
return {
|
|
519
|
+
docContents: doc.documentAfterEdits,
|
|
520
|
+
editsSoFar: stringEdit_1.StringEdit.empty,
|
|
521
|
+
nextEdits: [],
|
|
522
|
+
docId: id,
|
|
523
|
+
};
|
|
524
|
+
});
|
|
525
|
+
const editStream = this._statelessNextEditProvider.provideNextEdit(nextEditRequest, logger, logContext, nextEditRequest.cancellationTokenSource.token);
|
|
526
|
+
let ithEdit = -1;
|
|
527
|
+
const processEdit = (streamedEdit, telemetry) => {
|
|
528
|
+
++ithEdit;
|
|
529
|
+
const myLogger = logger.createSubLogger('processEdit');
|
|
530
|
+
myLogger.trace(`processing edit #${ithEdit} (starts at 0)`);
|
|
531
|
+
// reset shouldExpandEditWindow to false when we get any edit
|
|
532
|
+
myLogger.trace('resetting shouldExpandEditWindow to false due to receiving an edit');
|
|
533
|
+
this._shouldExpandEditWindow = false;
|
|
534
|
+
const targetDocState = statePerDoc.get(streamedEdit.targetDocument ?? curDocId);
|
|
535
|
+
const singleLineEdit = streamedEdit.edit;
|
|
536
|
+
const lineEdit = new lineEdit_1.LineEdit([singleLineEdit]);
|
|
537
|
+
const edit = convertLineEditToEdit(lineEdit, projectedDocuments, targetDocState.docId);
|
|
538
|
+
const rebasedEdit = edit.tryRebase(targetDocState.editsSoFar);
|
|
539
|
+
if (rebasedEdit === undefined) {
|
|
540
|
+
myLogger.trace(`edit ${ithEdit} is undefined after rebasing`);
|
|
541
|
+
if (!firstEdit.isSettled) {
|
|
542
|
+
firstEdit.complete(result_1.Result.error(new statelessNextEditProvider_1.NoNextEditReason.Uncategorized(new Error('Rebased edit is undefined'))));
|
|
477
543
|
}
|
|
478
|
-
|
|
479
|
-
|
|
544
|
+
return undefined;
|
|
545
|
+
}
|
|
546
|
+
targetDocState.editsSoFar = targetDocState.editsSoFar.compose(rebasedEdit);
|
|
547
|
+
let cachedEdit;
|
|
548
|
+
if (rebasedEdit.replacements.length === 0) {
|
|
549
|
+
myLogger.trace(`WARNING: ${ithEdit} has no edits`);
|
|
550
|
+
}
|
|
551
|
+
else if (rebasedEdit.replacements.length > 1) {
|
|
552
|
+
myLogger.trace(`WARNING: ${ithEdit} has ${rebasedEdit.replacements.length} edits, but expected only 1`);
|
|
553
|
+
}
|
|
554
|
+
else {
|
|
555
|
+
// populate the cache
|
|
556
|
+
const nextEditReplacement = rebasedEdit.replacements[0];
|
|
557
|
+
targetDocState.nextEdits.push(nextEditReplacement);
|
|
558
|
+
cachedEdit = this._nextEditCache.setKthNextEdit(targetDocState.docId, targetDocState.docContents, ithEdit === 0 ? streamedEdit.window : undefined, nextEditReplacement, ithEdit, ithEdit === 0 ? targetDocState.nextEdits : undefined, ithEdit === 0 ? nextEditRequest.intermediateUserEdit : undefined, req, { isFromCursorJump: streamedEdit.isFromCursorJump, originalEditWindow: streamedEdit.originalWindow });
|
|
559
|
+
myLogger.trace(`populated cache for ${ithEdit}`);
|
|
560
|
+
}
|
|
561
|
+
if (!firstEdit.isSettled) {
|
|
562
|
+
myLogger.trace('resolving firstEdit promise');
|
|
563
|
+
logContext.setResult(new rootedLineEdit_1.RootedLineEdit(targetDocState.docContents, lineEdit)); // this's correct without rebasing because this's the first edit
|
|
564
|
+
firstEdit.complete(cachedEdit ? result_1.Result.ok(cachedEdit) : result_1.Result.error(new statelessNextEditProvider_1.NoNextEditReason.Unexpected(new Error('No cached edit'))));
|
|
565
|
+
}
|
|
566
|
+
targetDocState.docContents = rebasedEdit.applyOnText(targetDocState.docContents);
|
|
567
|
+
return cachedEdit;
|
|
568
|
+
};
|
|
569
|
+
const handleStreamEnd = (completionReason, lastTelemetry) => {
|
|
570
|
+
const myLogger = logger.createSubLogger('streamEnd');
|
|
571
|
+
// if there was a request made, and it ended without any edits, reset shouldExpandEditWindow
|
|
572
|
+
const hadNoEdits = ithEdit === -1;
|
|
573
|
+
if (hadNoEdits && completionReason instanceof statelessNextEditProvider_1.NoNextEditReason.NoSuggestions) {
|
|
574
|
+
myLogger.trace('resetting shouldExpandEditWindow to false due to NoSuggestions');
|
|
480
575
|
this._shouldExpandEditWindow = false;
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
return;
|
|
492
|
-
}
|
|
493
|
-
targetDocState.editsSoFar = targetDocState.editsSoFar.compose(rebasedEdit);
|
|
494
|
-
let cachedEdit;
|
|
495
|
-
if (rebasedEdit.replacements.length === 0) {
|
|
496
|
-
myLogger.trace(`WARNING: ${ithEdit} has no edits`);
|
|
497
|
-
}
|
|
498
|
-
else if (rebasedEdit.replacements.length > 1) {
|
|
499
|
-
myLogger.trace(`WARNING: ${ithEdit} has ${rebasedEdit.replacements.length} edits, but expected only 1`);
|
|
500
|
-
}
|
|
501
|
-
else {
|
|
502
|
-
// populate the cache
|
|
503
|
-
const nextEdit = rebasedEdit.replacements[0];
|
|
504
|
-
targetDocState.nextEdits.push(nextEdit);
|
|
505
|
-
cachedEdit = this._nextEditCache.setKthNextEdit(targetDocState.docId, targetDocState.docContents, ithEdit === 0 ? result.val.window : undefined, nextEdit, ithEdit, ithEdit === 0 ? targetDocState.nextEdits : undefined, ithEdit === 0 ? nextEditRequest.intermediateUserEdit : undefined, req, { isFromCursorJump: result.val.isFromCursorJump });
|
|
506
|
-
myLogger.trace(`populated cache for ${ithEdit}`);
|
|
507
|
-
}
|
|
508
|
-
if (!firstEdit.isSettled) {
|
|
509
|
-
myLogger.trace('resolving firstEdit promise');
|
|
510
|
-
logContext.setResult(new rootedLineEdit_1.RootedLineEdit(targetDocState.docContents, lineEdit)); // this's correct without rebasing because this's the first edit
|
|
511
|
-
firstEdit.complete(cachedEdit ? result_1.Result.ok(cachedEdit) : result_1.Result.error(new statelessNextEditProvider_1.NoNextEditReason.Unexpected(new Error('No cached edit'))));
|
|
576
|
+
}
|
|
577
|
+
if (statePerDoc.get(curDocId).nextEdits.length) {
|
|
578
|
+
myLogger.trace(`${statePerDoc.get(curDocId).nextEdits.length} edits returned`);
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
myLogger.trace(`no edit, reason: ${completionReason.kind}`);
|
|
582
|
+
if (completionReason instanceof statelessNextEditProvider_1.NoNextEditReason.NoSuggestions) {
|
|
583
|
+
const { documentBeforeEdits, window } = completionReason;
|
|
584
|
+
const reducedWindow = window ? computeReducedWindow(window, activeDocSelection, documentBeforeEdits) : undefined;
|
|
585
|
+
this._nextEditCache.setNoNextEdit(curDocId, documentBeforeEdits, reducedWindow, req);
|
|
512
586
|
}
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
587
|
+
}
|
|
588
|
+
if (!firstEdit.isSettled) {
|
|
589
|
+
firstEdit.complete(result_1.Result.error(completionReason));
|
|
590
|
+
}
|
|
591
|
+
const resultForTelemetry = statePerDoc.get(curDocId).nextEdits.length > 0
|
|
592
|
+
? result_1.Result.ok(undefined)
|
|
593
|
+
: result_1.Result.error(completionReason);
|
|
594
|
+
const result = new statelessNextEditProvider_1.StatelessNextEditResult(resultForTelemetry, lastTelemetry);
|
|
595
|
+
nextEditRequest.setResult(result);
|
|
596
|
+
disp.dispose();
|
|
597
|
+
removeFromPending();
|
|
598
|
+
return result;
|
|
516
599
|
};
|
|
517
|
-
const pushEdit = createPushEdit();
|
|
518
600
|
try {
|
|
519
|
-
|
|
520
|
-
|
|
601
|
+
let res = await editStream.next();
|
|
602
|
+
if (res.done) {
|
|
603
|
+
// Stream ended immediately without any edits
|
|
604
|
+
const completionReason = res.value.v;
|
|
605
|
+
nextEditResult = handleStreamEnd(completionReason, res.value.telemetryBuilder);
|
|
606
|
+
}
|
|
607
|
+
else {
|
|
608
|
+
// Process first edit synchronously
|
|
609
|
+
const firstStreamedEdit = res.value.v;
|
|
610
|
+
const firstTelemetry = res.value.telemetryBuilder;
|
|
611
|
+
processEdit(firstStreamedEdit, firstTelemetry);
|
|
612
|
+
// Continue streaming remaining edits in the background (unawaited)
|
|
613
|
+
(async () => {
|
|
614
|
+
try {
|
|
615
|
+
res = await editStream.next();
|
|
616
|
+
while (!res.done) {
|
|
617
|
+
const streamedEdit = res.value.v;
|
|
618
|
+
processEdit(streamedEdit, res.value.telemetryBuilder);
|
|
619
|
+
res = await editStream.next();
|
|
620
|
+
}
|
|
621
|
+
// Stream completed
|
|
622
|
+
const completionReason = res.value.v;
|
|
623
|
+
handleStreamEnd(completionReason, res.value.telemetryBuilder);
|
|
624
|
+
}
|
|
625
|
+
catch (err) {
|
|
626
|
+
logger.trace(`Error while streaming further edits: ${errors.toString(err)}`);
|
|
627
|
+
const errorReason = new statelessNextEditProvider_1.NoNextEditReason.Unexpected(errors.fromUnknown(err));
|
|
628
|
+
handleStreamEnd(errorReason, firstTelemetry);
|
|
629
|
+
}
|
|
630
|
+
})();
|
|
631
|
+
// Return early with streaming result
|
|
632
|
+
nextEditResult = statelessNextEditProvider_1.StatelessNextEditResult.streaming(new statelessNextEditProvider_1.StatelessNextEditTelemetryBuilder(nextEditRequest.headerRequestId));
|
|
633
|
+
}
|
|
521
634
|
}
|
|
522
635
|
catch (err) {
|
|
523
636
|
nextEditRequest.setResultError(err);
|
|
524
637
|
throw err;
|
|
525
638
|
}
|
|
526
|
-
finally {
|
|
527
|
-
if (!nextEditResult || nextEditResult.nextEdit.isError()) {
|
|
528
|
-
// when streaming, we need to keep the response going unless UI cancels it
|
|
529
|
-
// if we remove it from pending here, when UI cancels, we cannot cancel it because we think that the request has finished
|
|
530
|
-
disp.dispose();
|
|
531
|
-
removeFromPending();
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
639
|
return { nextEditRequest, nextEditResult };
|
|
535
640
|
}
|
|
536
641
|
_hookupCancellation(nextEditRequest, cancellationToken, attachedDisposable) {
|
|
@@ -596,6 +701,235 @@ let NextEditProvider = class NextEditProvider extends lifecycle_1.Disposable {
|
|
|
596
701
|
}
|
|
597
702
|
handleShown(suggestion) {
|
|
598
703
|
this._lastShownTime = Date.now();
|
|
704
|
+
this._lastShownSuggestionId = suggestion.requestId;
|
|
705
|
+
// Trigger speculative request for the post-edit document state
|
|
706
|
+
const speculativeRequestsEnabled = this._configService.getExperimentBasedConfig(configurationService_1.ConfigKey.TeamInternal.InlineEditsSpeculativeRequests, this._expService);
|
|
707
|
+
if (speculativeRequestsEnabled) {
|
|
708
|
+
void this._triggerSpeculativeRequest(suggestion);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
async _triggerSpeculativeRequest(suggestion) {
|
|
712
|
+
const logger = this._logger.createSubLogger('_triggerSpeculativeRequest');
|
|
713
|
+
const result = suggestion.result;
|
|
714
|
+
if (!result?.edit) {
|
|
715
|
+
logger.trace('no edit in suggestion result');
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
const docId = result.targetDocumentId;
|
|
719
|
+
if (!docId) {
|
|
720
|
+
logger.trace('no target document ID in suggestion result');
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
// Compute the post-edit document content
|
|
724
|
+
const postEditContent = result.edit.replace(result.documentBeforeEdits.value);
|
|
725
|
+
const postEditCursorOffset = result.edit.replaceRange.endExclusive + result.edit.getLengthDelta();
|
|
726
|
+
const selections = [new offsetRange_1.OffsetRange(postEditCursorOffset, postEditCursorOffset)];
|
|
727
|
+
const rootedEdit = new edit_1.RootedEdit(result.documentBeforeEdits, new stringEdit_1.StringEdit([result.edit]));
|
|
728
|
+
const postEditContentST = new abstractText_1.StringText(postEditContent);
|
|
729
|
+
let cachedEdit = this._nextEditCache.lookupNextEdit(docId, postEditContentST, selections);
|
|
730
|
+
let shiftedSelection;
|
|
731
|
+
if (cachedEdit) {
|
|
732
|
+
// first cachedEdit should be without edits because of noSuggestions caching
|
|
733
|
+
if (cachedEdit.edit) {
|
|
734
|
+
logger.trace('already have cached edit for post-edit state');
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
else if (cachedEdit.editWindow) {
|
|
738
|
+
const trans = postEditContentST.getTransformer();
|
|
739
|
+
const endOfEditWindow = trans.getPosition(cachedEdit.editWindow.endExclusive - 1);
|
|
740
|
+
const shiftedCursorLineNumber = (endOfEditWindow.lineNumber + 1 < postEditContentST.lineRange.endLineNumberExclusive
|
|
741
|
+
? endOfEditWindow.lineNumber + 1
|
|
742
|
+
: endOfEditWindow.lineNumber);
|
|
743
|
+
const shiftedSelectionCursorOffset = trans.getOffset(new position_1.Position(shiftedCursorLineNumber, 1));
|
|
744
|
+
shiftedSelection = new offsetRange_1.OffsetRange(shiftedSelectionCursorOffset, shiftedSelectionCursorOffset);
|
|
745
|
+
cachedEdit = this._nextEditCache.lookupNextEdit(docId, postEditContentST, [shiftedSelection]);
|
|
746
|
+
if (cachedEdit?.edit) {
|
|
747
|
+
logger.trace('already have cached edit for post-edit state (after shifting selection)');
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
else {
|
|
752
|
+
logger.trace('already have cached no-suggestions entry for post-edit state');
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
// Check if we already have a pending request for the post-edit state
|
|
757
|
+
if (this._pendingStatelessNextEditRequest?.documentBeforeEdits.value === postEditContent) {
|
|
758
|
+
logger.trace('already have pending request for post-edit state');
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
// Check if we already have a speculative request for this post-edit state
|
|
762
|
+
if (this._speculativePendingRequest?.postEditContent === postEditContent) {
|
|
763
|
+
logger.trace('already have speculative request for post-edit state');
|
|
764
|
+
return;
|
|
765
|
+
}
|
|
766
|
+
// Get the document to trigger speculative fetch
|
|
767
|
+
// Note: targetDocumentId is defined when the suggestion targets a different document
|
|
768
|
+
// Otherwise, use the file path from the log context
|
|
769
|
+
const doc = this._workspace.getDocument(docId);
|
|
770
|
+
if (!doc) {
|
|
771
|
+
logger.trace('document not found for speculative request');
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
// Cancel any previous speculative request
|
|
775
|
+
this._speculativePendingRequest?.request.cancellationTokenSource.cancel();
|
|
776
|
+
this._speculativePendingRequest = null;
|
|
777
|
+
const historyContext = this._historyContextProvider.getHistoryContext(docId);
|
|
778
|
+
if (!historyContext) {
|
|
779
|
+
logger.trace('no history context for speculative request');
|
|
780
|
+
return;
|
|
781
|
+
}
|
|
782
|
+
// Create a speculative request
|
|
783
|
+
// Use a dummy version since this is speculative and we don't have the actual post-edit version
|
|
784
|
+
const logContext = new inlineEditLogContext_1.InlineEditRequestLogContext(docId.uri, 0, undefined);
|
|
785
|
+
const req = new NextEditFetchRequest(`sp-${suggestion.source.opportunityId}`, logContext, undefined, `sp-${(0, uuid_1.generateUuid)()}`);
|
|
786
|
+
logger.trace(`triggering speculative request for post-edit state (opportunityId=${req.opportunityId}, headerRequestId=${req.headerRequestId})`);
|
|
787
|
+
logger.trace(`triggering speculative request for post-edit state (opportunityId=${req.opportunityId}, headerRequestId=${req.headerRequestId})`);
|
|
788
|
+
try {
|
|
789
|
+
const speculativeRequest = await this._createSpeculativeRequest(req, doc, shiftedSelection, historyContext, postEditContent, rootedEdit, result.edit, logger);
|
|
790
|
+
if (speculativeRequest) {
|
|
791
|
+
this._speculativePendingRequest = {
|
|
792
|
+
request: speculativeRequest,
|
|
793
|
+
postEditContent,
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
catch (e) {
|
|
798
|
+
logger.trace(`speculative request failed: ${errors.toString(e)}`);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Creates and starts a speculative request for the post-edit document state.
|
|
803
|
+
* The request will populate the cache so that when the user accepts the suggestion,
|
|
804
|
+
* the next NES request can reuse or find the result in cache.
|
|
805
|
+
*/
|
|
806
|
+
async _createSpeculativeRequest(req, doc, shiftedSelection, historyContext, postEditContent, rootedEdit, appliedEdit, parentLogger) {
|
|
807
|
+
const logger = parentLogger.createSubLogger('_createSpeculativeRequest');
|
|
808
|
+
const curDocId = doc.id;
|
|
809
|
+
const recording = this._debugRecorder?.getRecentLog();
|
|
810
|
+
const logContext = req.log;
|
|
811
|
+
const activeDocAndIdx = historyContext.getDocumentAndIdx(curDocId);
|
|
812
|
+
if (!activeDocAndIdx) {
|
|
813
|
+
logger.trace('active doc not found in history context');
|
|
814
|
+
return undefined;
|
|
815
|
+
}
|
|
816
|
+
// Create the post-edit document content
|
|
817
|
+
const postEditText = new abstractText_1.StringText(postEditContent);
|
|
818
|
+
// Process documents, but for the active document, use the post-edit state
|
|
819
|
+
const projectedDocuments = historyContext.documents.map(docHist => {
|
|
820
|
+
if (docHist.docId !== curDocId) {
|
|
821
|
+
return this._processDoc(docHist);
|
|
822
|
+
}
|
|
823
|
+
else {
|
|
824
|
+
// For the active document, create a version representing post-edit state
|
|
825
|
+
// The "recent edit" from the model's perspective is the NES edit we just applied
|
|
826
|
+
const workspaceRoot = this._workspace.getWorkspaceRoot(curDocId);
|
|
827
|
+
const postEditEdit = new stringEdit_1.StringEdit([appliedEdit]);
|
|
828
|
+
const postEditLineEdit = rootedLineEdit_1.RootedLineEdit.fromEdit(new edit_1.RootedEdit(doc.value.get(), postEditEdit)).removeCommonSuffixPrefixLines().edit;
|
|
829
|
+
let selection = shiftedSelection;
|
|
830
|
+
if (selection === undefined) {
|
|
831
|
+
const appliedEditEndPos = postEditText.getTransformer().getPosition(appliedEdit.replaceRange.endExclusive + appliedEdit.getLengthDelta());
|
|
832
|
+
const pos = new position_1.Position(appliedEditEndPos.lineNumber, 1);
|
|
833
|
+
const offset = postEditText.getTransformer().getOffset(pos);
|
|
834
|
+
selection = new offsetRange_1.OffsetRange(offset, offset);
|
|
835
|
+
}
|
|
836
|
+
const nextEditDoc = new statelessNextEditProvider_1.StatelessNextEditDocument(curDocId, workspaceRoot, docHist.languageId, doc.value.get().getLines(), // lines before the NES edit
|
|
837
|
+
postEditLineEdit, // the NES edit as LineEdit
|
|
838
|
+
doc.value.get(), // document before NES edit
|
|
839
|
+
edit_1.Edits.single(postEditEdit), // the NES edit as Edits
|
|
840
|
+
selection);
|
|
841
|
+
return {
|
|
842
|
+
recentEdit: new edit_1.RootedEdit(doc.value.get(), postEditEdit),
|
|
843
|
+
nextEditDoc,
|
|
844
|
+
documentAfterEdits: postEditText,
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
});
|
|
848
|
+
const xtabEditHistory = this._xtabHistoryTracker.getHistory();
|
|
849
|
+
const suggestedEdit = { kind: 'edit', docId: curDocId, edit: rootedEdit };
|
|
850
|
+
xtabEditHistory.push(suggestedEdit);
|
|
851
|
+
const firstEdit = new async_1.DeferredPromise();
|
|
852
|
+
const nLinesEditWindow = this._configService.getExperimentBasedConfig(configurationService_1.ConfigKey.TeamInternal.InlineEditsAutoExpandEditWindowLines, this._expService);
|
|
853
|
+
const nextEditRequest = new statelessNextEditProvider_1.StatelessNextEditRequest(req.headerRequestId, req.opportunityId, postEditText, // documentBeforeEdits is the post-edit state
|
|
854
|
+
projectedDocuments.map(d => d.nextEditDoc), activeDocAndIdx.idx, xtabEditHistory, firstEdit, nLinesEditWindow, logContext, undefined, // recordingBookmark
|
|
855
|
+
recording, undefined);
|
|
856
|
+
logger.trace('starting speculative provider call');
|
|
857
|
+
// Start the provider call - this runs in the background and populates the cache
|
|
858
|
+
const label = `NES | spec | ${(0, path_1.basename)(doc.id.toUri().fsPath)} (v${doc.version})`;
|
|
859
|
+
const capturingToken = new capturingToken_1.CapturingToken(label, undefined, true, true);
|
|
860
|
+
void this._requestLogger.captureInvocation(capturingToken, () => this._runSpeculativeProviderCall(nextEditRequest, projectedDocuments, curDocId, req, logger));
|
|
861
|
+
return nextEditRequest;
|
|
862
|
+
}
|
|
863
|
+
/**
|
|
864
|
+
* Runs the provider call for a speculative request and caches results.
|
|
865
|
+
*/
|
|
866
|
+
async _runSpeculativeProviderCall(nextEditRequest, projectedDocuments, curDocId, req, parentLogger) {
|
|
867
|
+
const logger = parentLogger.createSubLogger('_runSpeculativeProviderCall');
|
|
868
|
+
const statePerDoc = new cache_1.CachedFunction((id) => {
|
|
869
|
+
const doc = projectedDocuments.find(d => d.nextEditDoc.id === id);
|
|
870
|
+
if (!doc) {
|
|
871
|
+
throw new errors_1.BugIndicatingError();
|
|
872
|
+
}
|
|
873
|
+
return {
|
|
874
|
+
docContents: doc.documentAfterEdits,
|
|
875
|
+
editsSoFar: stringEdit_1.StringEdit.empty,
|
|
876
|
+
nextEdits: [],
|
|
877
|
+
docId: id,
|
|
878
|
+
};
|
|
879
|
+
});
|
|
880
|
+
const logContext = req.log;
|
|
881
|
+
const editStream = this._statelessNextEditProvider.provideNextEdit(nextEditRequest, logger, logContext, nextEditRequest.cancellationTokenSource.token);
|
|
882
|
+
let ithEdit = -1;
|
|
883
|
+
try {
|
|
884
|
+
let res = await editStream.next();
|
|
885
|
+
if (res.done) {
|
|
886
|
+
nextEditRequest.firstEdit.complete(result_1.Result.error(res.value.v));
|
|
887
|
+
nextEditRequest.setResult(new statelessNextEditProvider_1.StatelessNextEditResult(result_1.Result.error(res.value.v), res.value.telemetryBuilder));
|
|
888
|
+
logger.trace('speculative request completed with no edits');
|
|
889
|
+
}
|
|
890
|
+
else {
|
|
891
|
+
(async () => {
|
|
892
|
+
while (!res.done) {
|
|
893
|
+
++ithEdit;
|
|
894
|
+
const streamedEdit = res.value.v;
|
|
895
|
+
const targetDocState = statePerDoc.get(streamedEdit.targetDocument ?? curDocId);
|
|
896
|
+
const singleLineEdit = streamedEdit.edit;
|
|
897
|
+
const lineEdit = new lineEdit_1.LineEdit([singleLineEdit]);
|
|
898
|
+
const edit = convertLineEditToEdit(lineEdit, projectedDocuments, targetDocState.docId);
|
|
899
|
+
const rebasedEdit = edit.tryRebase(targetDocState.editsSoFar);
|
|
900
|
+
if (rebasedEdit === undefined) {
|
|
901
|
+
logger.trace(`speculative edit ${ithEdit} rebasing failed`);
|
|
902
|
+
res = await editStream.next();
|
|
903
|
+
continue;
|
|
904
|
+
}
|
|
905
|
+
targetDocState.editsSoFar = targetDocState.editsSoFar.compose(rebasedEdit);
|
|
906
|
+
if (rebasedEdit.replacements.length === 1) {
|
|
907
|
+
const nextEditReplacement = rebasedEdit.replacements[0];
|
|
908
|
+
targetDocState.nextEdits.push(nextEditReplacement);
|
|
909
|
+
// Populate the cache with the speculative result
|
|
910
|
+
const cachedEdit = this._nextEditCache.setKthNextEdit(targetDocState.docId, targetDocState.docContents, ithEdit === 0 ? streamedEdit.window : undefined, nextEditReplacement, ithEdit, ithEdit === 0 ? targetDocState.nextEdits : undefined, undefined, // no userEditSince for speculative
|
|
911
|
+
req, { isFromCursorJump: streamedEdit.isFromCursorJump, originalEditWindow: streamedEdit.originalWindow });
|
|
912
|
+
if (!nextEditRequest.firstEdit.isSettled && cachedEdit) {
|
|
913
|
+
nextEditRequest.firstEdit.complete(result_1.Result.ok(cachedEdit));
|
|
914
|
+
nextEditRequest.setResult(new statelessNextEditProvider_1.StatelessNextEditResult(result_1.Result.ok(undefined), res.value.telemetryBuilder));
|
|
915
|
+
}
|
|
916
|
+
logger.trace(`cached speculative edit ${ithEdit}`);
|
|
917
|
+
}
|
|
918
|
+
targetDocState.docContents = rebasedEdit.applyOnText(targetDocState.docContents);
|
|
919
|
+
res = await editStream.next();
|
|
920
|
+
}
|
|
921
|
+
})().finally(() => {
|
|
922
|
+
if (!nextEditRequest.firstEdit.isSettled) {
|
|
923
|
+
nextEditRequest.firstEdit.complete(result_1.Result.error(new statelessNextEditProvider_1.NoNextEditReason.Uncategorized(new Error('Speculative request ended without edits'))));
|
|
924
|
+
nextEditRequest.setResult(new statelessNextEditProvider_1.StatelessNextEditResult(result_1.Result.error(new statelessNextEditProvider_1.NoNextEditReason.Uncategorized(new Error('Speculative request ended without edits'))), res.value.telemetryBuilder));
|
|
925
|
+
}
|
|
926
|
+
});
|
|
927
|
+
}
|
|
928
|
+
logger.trace(`speculative request completed with ${ithEdit + 1} edits`);
|
|
929
|
+
}
|
|
930
|
+
catch (e) {
|
|
931
|
+
logger.trace(`speculative provider call error: ${errors.toString(e)}`);
|
|
932
|
+
}
|
|
599
933
|
}
|
|
600
934
|
handleAcceptance(docId, suggestion) {
|
|
601
935
|
this.runSnippy(docId, suggestion);
|
|
@@ -621,7 +955,15 @@ let NextEditProvider = class NextEditProvider extends lifecycle_1.Disposable {
|
|
|
621
955
|
this._lastRejectionTime = Date.now();
|
|
622
956
|
this._statelessNextEditProvider.handleRejection?.();
|
|
623
957
|
}
|
|
624
|
-
handleIgnored(docId, suggestion, supersededBy) {
|
|
958
|
+
handleIgnored(docId, suggestion, supersededBy) {
|
|
959
|
+
// Check if this was the last shown suggestion
|
|
960
|
+
const wasShown = this._lastShownSuggestionId === suggestion.requestId;
|
|
961
|
+
const wasSuperseded = supersededBy !== undefined;
|
|
962
|
+
if (wasShown && !wasSuperseded) {
|
|
963
|
+
// Was shown to the user
|
|
964
|
+
this._statelessNextEditProvider.handleIgnored?.();
|
|
965
|
+
}
|
|
966
|
+
}
|
|
625
967
|
async runSnippy(docId, suggestion) {
|
|
626
968
|
if (suggestion.result === undefined || suggestion.result.edit === undefined) {
|
|
627
969
|
return;
|
|
@@ -638,7 +980,8 @@ exports.NextEditProvider = NextEditProvider = __decorate([
|
|
|
638
980
|
__param(5, configurationService_1.IConfigurationService),
|
|
639
981
|
__param(6, snippyService_1.ISnippyService),
|
|
640
982
|
__param(7, logService_1.ILogService),
|
|
641
|
-
__param(8, nullExperimentationService_1.IExperimentationService)
|
|
983
|
+
__param(8, nullExperimentationService_1.IExperimentationService),
|
|
984
|
+
__param(9, requestLogger_1.IRequestLogger)
|
|
642
985
|
], NextEditProvider);
|
|
643
986
|
function assertDefined(value) {
|
|
644
987
|
if (!value) {
|
|
@@ -647,11 +990,11 @@ function assertDefined(value) {
|
|
|
647
990
|
return value;
|
|
648
991
|
}
|
|
649
992
|
class NextEditFetchRequest {
|
|
650
|
-
constructor(opportunityId, log, providerRequestStartDateTime) {
|
|
993
|
+
constructor(opportunityId, log, providerRequestStartDateTime, headerRequestId = (0, uuid_1.generateUuid)()) {
|
|
651
994
|
this.opportunityId = opportunityId;
|
|
652
995
|
this.log = log;
|
|
653
996
|
this.providerRequestStartDateTime = providerRequestStartDateTime;
|
|
654
|
-
this.headerRequestId =
|
|
997
|
+
this.headerRequestId = headerRequestId;
|
|
655
998
|
}
|
|
656
999
|
}
|
|
657
1000
|
exports.NextEditFetchRequest = NextEditFetchRequest;
|