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