diff --git a/extensions/copilot/src/extension/xtab/node/xtabNextCursorPredictor.ts b/extensions/copilot/src/extension/xtab/node/xtabNextCursorPredictor.ts index 2477e1e3c04..d2b0fd467e5 100644 --- a/extensions/copilot/src/extension/xtab/node/xtabNextCursorPredictor.ts +++ b/extensions/copilot/src/extension/xtab/node/xtabNextCursorPredictor.ts @@ -16,6 +16,7 @@ import { ILanguageDiagnosticsService } from '../../../platform/languages/common/ import { ILogger } from '../../../platform/log/common/logService'; import { OptionalChatRequestParams } from '../../../platform/networking/common/fetch'; import { IChatEndpoint } from '../../../platform/networking/common/networking'; +import { IProxyModelsService } from '../../../platform/proxyModels/common/proxyModelsService'; import { IExperimentationService } from '../../../platform/telemetry/common/nullExperimentationService'; import { backwardCompatSetting } from '../../../util/common/backwardCompatSetting'; import { ErrorUtils } from '../../../util/common/errors'; @@ -33,6 +34,8 @@ export type CursorJumpPrediction = | { readonly kind: 'sameFile'; readonly lineNumber: number } | { readonly kind: 'differentFile'; readonly filePath: string; readonly lineNumber: number }; +const DEFAULT_CURSOR_JUMP_MODEL_NAME = 'copilot-suggestions-himalia-001'; + export class XtabNextCursorPredictor { private isDisabled: boolean; @@ -44,6 +47,7 @@ export class XtabNextCursorPredictor { @IExperimentationService private readonly expService: IExperimentationService, @ILanguageDiagnosticsService private readonly langDiagService: ILanguageDiagnosticsService, @IEndpointProvider private readonly endpointProvider: IEndpointProvider, + @IProxyModelsService private readonly proxyModelsService: IProxyModelsService, ) { this.isDisabled = false; } @@ -161,11 +165,7 @@ export class XtabNextCursorPredictor { telemetryBuilder?.setCursorJumpPrompt(messages); - const modelName = this.configService.getExperimentBasedConfig(ConfigKey.TeamInternal.InlineEditsNextCursorPredictionModelName, this.expService); - if (modelName === undefined) { - tracer.trace('Model name for cursor prediction is not defined; skipping prediction'); - return Result.fromString('modelNameNotDefined'); - } + const modelName = this.determineModelName(); telemetryBuilder?.setCursorJumpModelName(modelName); const resolvedEndpoint = await this.resolveEndpoint(modelName, tracer); @@ -260,6 +260,14 @@ export class XtabNextCursorPredictor { }; } + private determineModelName(): string { + // Priority: experiment-configured model name, then the first `CursorJumpChat` + // model advertised by the `/models` endpoint, then a hard-coded fallback. + return this.configService.getExperimentBasedConfig(ConfigKey.TeamInternal.InlineEditsNextCursorPredictionModelName, this.expService) + ?? this.proxyModelsService.cursorJumpModels?.[0]?.name + ?? DEFAULT_CURSOR_JUMP_MODEL_NAME; + } + private determineLintOptions(): xtabPromptOptions.LintOptions | undefined { const localLintOptions = this.configService.getConfig(ConfigKey.TeamInternal.InlineEditsNextCursorPredictionLintOptions); if (localLintOptions) { diff --git a/extensions/copilot/src/platform/configuration/common/configurationService.ts b/extensions/copilot/src/platform/configuration/common/configurationService.ts index fdc50dab3a6..8bfde61c5c7 100644 --- a/extensions/copilot/src/platform/configuration/common/configurationService.ts +++ b/extensions/copilot/src/platform/configuration/common/configurationService.ts @@ -810,7 +810,7 @@ export namespace ConfigKey { export const InlineEditsTriggerOnEditorChangeStrategy = defineTeamInternalSetting('chat.advanced.inlineEdits.triggerOnEditorChangeStrategy', ConfigType.ExperimentBased, triggerOptions.DocumentSwitchTriggerStrategy.AfterAcceptance, triggerOptions.DocumentSwitchTriggerStrategy.VALIDATOR); export const InlineEditsProviderId = defineTeamInternalSetting('chat.advanced.inlineEdits.providerId', ConfigType.ExperimentBased, undefined); export const InlineEditsUnification = defineTeamInternalSetting('chat.advanced.inlineEdits.unification', ConfigType.ExperimentBased, false); - export const InlineEditsNextCursorPredictionModelName = defineTeamInternalSetting('chat.advanced.inlineEdits.nextCursorPrediction.modelName', ConfigType.ExperimentBased, 'copilot-suggestions-himalia-001'); + export const InlineEditsNextCursorPredictionModelName = defineTeamInternalSetting('chat.advanced.inlineEdits.nextCursorPrediction.modelName', ConfigType.ExperimentBased, undefined); export const InlineEditsNextCursorPredictionUseEndpointProvider = defineTeamInternalSetting('chat.advanced.inlineEdits.nextCursorPrediction.useEndpointProvider', ConfigType.Simple, false, vBoolean()); export const InlineEditsNextCursorPredictionMaxResponseTokens = defineTeamInternalSetting('chat.advanced.inlineEdits.nextCursorPrediction.maxResponseTokens', ConfigType.ExperimentBased, 40); export const InlineEditsNextCursorPredictionLintOptionsString = defineTeamInternalSetting('chat.advanced.inlineEdits.nextCursorPrediction.lintOptionsString', ConfigType.ExperimentBased, undefined); diff --git a/extensions/copilot/src/platform/proxyModels/common/proxyModelsService.ts b/extensions/copilot/src/platform/proxyModels/common/proxyModelsService.ts index 2b572de6669..f3b3e0c5845 100644 --- a/extensions/copilot/src/platform/proxyModels/common/proxyModelsService.ts +++ b/extensions/copilot/src/platform/proxyModels/common/proxyModelsService.ts @@ -14,6 +14,7 @@ export interface IProxyModelsService { readonly models: WireTypes.ModelList.t | undefined; readonly nesModels: WireTypes.Model.t[] | undefined; + readonly cursorJumpModels: WireTypes.Model.t[] | undefined; readonly instantApplyModels: WireTypes.Model.t[] | undefined; } @@ -32,6 +33,10 @@ export class NullProxyModelsService implements IProxyModelsService { return undefined; } + get cursorJumpModels(): WireTypes.Model.t[] | undefined { + return undefined; + } + get instantApplyModels(): WireTypes.Model.t[] | undefined { return undefined; } diff --git a/extensions/copilot/src/platform/proxyModels/node/proxyModelsService.ts b/extensions/copilot/src/platform/proxyModels/node/proxyModelsService.ts index 18d8eea0d87..57a6aab70ce 100644 --- a/extensions/copilot/src/platform/proxyModels/node/proxyModelsService.ts +++ b/extensions/copilot/src/platform/proxyModels/node/proxyModelsService.ts @@ -66,6 +66,10 @@ export class ProxyModelsService extends Disposable implements IProxyModelsServic return this._models?.models.filter(model => model.serviceType === 'NESChat'); } + get cursorJumpModels(): WireTypes.Model.t[] | undefined { + return this._models?.models.filter(model => model.serviceType === 'CursorJumpChat'); + } + get instantApplyModels(): WireTypes.Model.t[] | undefined { return this._models?.models.filter(model => model.serviceType === 'InstantApplyChat'); }