Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4016,7 +4016,7 @@
},
"github.copilot.chat.searchSubagent.enabled": {
"type": "boolean",
"default": false,
"default": true,
"markdownDescription": "%github.copilot.config.searchSubagent.enabled%",
"tags": [
"advanced",
Expand Down
17 changes: 7 additions & 10 deletions src/extension/prompt/node/searchSubagentToolCallingLoop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { IAuthenticationChatUpgradeService } from '../../../platform/authenticat
import { ChatLocation, ChatResponse } from '../../../platform/chat/common/commonTypes';
import { IConfigurationService } from '../../../platform/configuration/common/configurationService';
import { IEndpointProvider } from '../../../platform/endpoint/common/endpointProvider';
import { ProxyAgenticSearchEndpoint } from '../../../platform/endpoint/node/proxyAgenticSearchEndpoint';
import { ILogService } from '../../../platform/log/common/logService';
import { IRequestLogger } from '../../../platform/requestLogger/node/requestLogger';
import { IExperimentationService } from '../../../platform/telemetry/common/nullExperimentationService';
Expand Down Expand Up @@ -38,7 +39,7 @@ export class SearchSubagentToolCallingLoop extends ToolCallingLoop<ISearchSubage
@IInstantiationService private readonly instantiationService: IInstantiationService,
@ILogService logService: ILogService,
@IRequestLogger requestLogger: IRequestLogger,
@IEndpointProvider private readonly endpointProvider: IEndpointProvider,
@IEndpointProvider endpointProvider: IEndpointProvider,
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The endpointProvider parameter is no longer used in this class after the refactoring to always use ProxyAgenticSearchEndpoint. This parameter should be removed from the constructor entirely, along with the corresponding parameter in the super() call on line 49. The base class ToolCallingLoop still requires it, but this derived class doesn't need to accept it as a constructor parameter.

Copilot uses AI. Check for mistakes.
@IToolsService private readonly toolsService: IToolsService,
@IAuthenticationChatUpgradeService authenticationChatUpgradeService: IAuthenticationChatUpgradeService,
@ITelemetryService telemetryService: ITelemetryService,
Expand All @@ -61,16 +62,12 @@ export class SearchSubagentToolCallingLoop extends ToolCallingLoop<ISearchSubage
return context;
}

private async getEndpoint(request: ChatRequest) {
let endpoint = await this.endpointProvider.getChatEndpoint(this.options.request);
if (!endpoint.supportsToolCalls) {
endpoint = await this.endpointProvider.getChatEndpoint('gpt-4.1');
}
return endpoint;
private async getEndpoint() {
return this.instantiationService.createInstance(ProxyAgenticSearchEndpoint);
}

protected async buildPrompt(buildPromptContext: IBuildPromptContext, progress: Progress<ChatResponseReferencePart | ChatResponseProgressPart>, token: CancellationToken): Promise<IBuildPromptResult> {
const endpoint = await this.getEndpoint(this.options.request);
const endpoint = await this.getEndpoint();
const renderer = PromptRenderer.create(
this.instantiationService,
endpoint,
Expand All @@ -83,7 +80,7 @@ export class SearchSubagentToolCallingLoop extends ToolCallingLoop<ISearchSubage
}

protected async getAvailableTools(): Promise<LanguageModelToolInformation[]> {
const endpoint = await this.getEndpoint(this.options.request);
const endpoint = await this.getEndpoint();
const allTools = this.toolsService.getEnabledTools(this.options.request, endpoint);

// Only include tools relevant for search operations.
Expand All @@ -100,7 +97,7 @@ export class SearchSubagentToolCallingLoop extends ToolCallingLoop<ISearchSubage
}

protected async fetch({ messages, finishedCb, requestOptions }: ToolCallingLoopFetchOptions, token: CancellationToken): Promise<ChatResponse> {
const endpoint = await this.getEndpoint(this.options.request);
const endpoint = await this.getEndpoint();
return endpoint.makeChatRequest2({
debugName: SearchSubagentToolCallingLoop.ID,
messages,
Expand Down
2 changes: 1 addition & 1 deletion src/platform/configuration/common/configurationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ export namespace ConfigKey {
export const PromptFileContext = defineAndMigrateExpSetting<boolean>('chat.advanced.promptFileContextProvider.enabled', 'chat.promptFileContextProvider.enabled', true);
export const DefaultToolsGrouped = defineAndMigrateExpSetting<boolean>('chat.advanced.tools.defaultToolsGrouped', 'chat.tools.defaultToolsGrouped', false);
export const Gpt5AlternativePatch = defineAndMigrateExpSetting<boolean>('chat.advanced.gpt5AlternativePatch', 'chat.gpt5AlternativePatch', false);
export const SearchSubagentToolEnabled = defineSetting<boolean>('chat.searchSubagent.enabled', ConfigType.ExperimentBased, false);
export const SearchSubagentToolEnabled = defineSetting<boolean>('chat.searchSubagent.enabled', ConfigType.ExperimentBased, true);
export const InlineEditsTriggerOnEditorChangeAfterSeconds = defineAndMigrateExpSetting<number | undefined>('chat.advanced.inlineEdits.triggerOnEditorChangeAfterSeconds', 'chat.inlineEdits.triggerOnEditorChangeAfterSeconds', undefined);
export const InlineEditsNextCursorPredictionDisplayLine = defineAndMigrateExpSetting<boolean>('chat.advanced.inlineEdits.nextCursorPrediction.displayLine', 'chat.inlineEdits.nextCursorPrediction.displayLine', true);
export const InlineEditsNextCursorPredictionCurrentFileMaxTokens = defineAndMigrateExpSetting<number>('chat.advanced.inlineEdits.nextCursorPrediction.currentFileMaxTokens', 'chat.inlineEdits.nextCursorPrediction.currentFileMaxTokens', xtabPromptOptions.DEFAULT_OPTIONS.currentFile.maxTokens);
Expand Down
75 changes: 75 additions & 0 deletions src/platform/endpoint/node/proxyAgenticSearchEndpoint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { RequestType } from '@vscode/copilot-api';
import { TokenizerType } from '../../../util/common/tokenizer';
import { IInstantiationService } from '../../../util/vs/platform/instantiation/common/instantiation';
import { IAuthenticationService } from '../../authentication/common/authentication';
import { IChatMLFetcher } from '../../chat/common/chatMLFetcher';
import { IConfigurationService } from '../../configuration/common/configurationService';
import { ILogService } from '../../log/common/logService';
import { IFetcherService } from '../../networking/common/fetcherService';
import { IExperimentationService } from '../../telemetry/common/nullExperimentationService';
import { ITelemetryService } from '../../telemetry/common/telemetry';
import { ITokenizerProvider } from '../../tokenizer/node/tokenizer';
import { ICAPIClientService } from '../common/capiClient';
import { IDomainService } from '../common/domainService';
import { IChatModelInformation } from '../common/endpointProvider';
import { ChatEndpoint } from './chatEndpoint';

export class ProxyAgenticSearchEndpoint extends ChatEndpoint {

constructor(
@IDomainService domainService: IDomainService,
@ICAPIClientService capiClientService: ICAPIClientService,
@IFetcherService fetcherService: IFetcherService,
@ITelemetryService telemetryService: ITelemetryService,
@IAuthenticationService authService: IAuthenticationService,
@IChatMLFetcher chatMLFetcher: IChatMLFetcher,
@ITokenizerProvider tokenizerProvider: ITokenizerProvider,
@IInstantiationService instantiationService: IInstantiationService,
@IConfigurationService configurationService: IConfigurationService,
@IExperimentationService experimentationService: IExperimentationService,
@ILogService logService: ILogService,
) {
const model = 'agentic-search-v1';
const modelInfo: IChatModelInformation = {
id: model,
name: model,
version: 'unknown',
model_picker_enabled: false,
is_chat_default: false,
is_chat_fallback: false,
capabilities: {
type: 'chat',
family: model,
tokenizer: TokenizerType.O200K,
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tokenizer type O200K is typically associated with OpenAI's GPT-4 and GPT-4o models. According to the PR description, this endpoint is for a fine-tuned Qwen3-4b model. Verify that O200K is the correct tokenizer for this model, as Qwen models typically use their own tokenizers. If the model was fine-tuned to be compatible with O200K tokenization, this is acceptable, but it should be documented why this choice was made.

Suggested change
tokenizer: TokenizerType.O200K,
tokenizer: TokenizerType.Unknown,

Copilot uses AI. Check for mistakes.
supports: { streaming: true, parallel_tool_calls: true, tool_calls: true, vision: false },
limits: {
max_prompt_tokens: 128000,
max_output_tokens: 16000,
}
}
};
super(
modelInfo,
domainService,
capiClientService,
fetcherService,
telemetryService,
authService,
chatMLFetcher,
tokenizerProvider,
instantiationService,
configurationService,
experimentationService,
logService
);
}

override get urlOrRequestMetadata() {
return { type: RequestType.ProxyChatCompletions };
}
}
Loading