Skip to content

Support editTools configuration for BYOK models in copilot chat extension #297178

@yuezhang030

Description

@yuezhang030

We would like to propose adding editTools to the Copilot Chat model selection configuration, as shown below:

customModels:
  customoai:
    vscModelB-oswe-omai-d36-mix1-r3-rl2-s105-0216:
      name: "vscModelB-oswe-omai-d36-mix1-r3-rl2-s105-0216"
      url: "https://github-research-aoai-eastus2.openai.azure.com/openai/responses?api-version=2025-04-01-preview"
      toolCalling: true
      vision: false
      thinking: true
      maxInputTokens: 200000
      maxOutputTokens: 64000
      requiresAPIKey: true
      editTools:
        - "find-replace"
        - "multi-find-replace"

We expect the editTools configuration to work for custom models. However, it is currently not functioning as intended.

We have identified a viable fix, as demonstrated in the following code patch:

diff --git a/src/extension/byok/common/byokProvider.ts b/src/extension/byok/common/byokProvider.ts
index 23413e39..01aa3ab7 100644
--- a/src/extension/byok/common/byokProvider.ts
+++ b/src/extension/byok/common/byokProvider.ts
@@ -146,6 +146,9 @@ export function resolveModelInfo(modelId: string, providerName: string, knownMod
 	if (knownModelInfo?.requestHeaders && Object.keys(knownModelInfo.requestHeaders).length > 0) {
 		modelInfo.requestHeaders = { ...knownModelInfo.requestHeaders };
 	}
+	if (knownModelInfo?.editTools && knownModelInfo.editTools.length > 0) {
+		modelInfo.editTools = knownModelInfo.editTools;
+	}
 	return modelInfo;
 }
 
diff --git a/src/extension/byok/vscode-node/customOAIProvider.ts b/src/extension/byok/vscode-node/customOAIProvider.ts
index 772e2cf4..b3d705d1 100644
--- a/src/extension/byok/vscode-node/customOAIProvider.ts
+++ b/src/extension/byok/vscode-node/customOAIProvider.ts
@@ -142,7 +142,8 @@ export abstract class AbstractCustomOAIBYOKModelProvider extends AbstractOpenAIC
 			thinking: modelConfiguration?.thinking ?? false,
 			streaming: modelConfiguration?.streaming,
 			requestHeaders: modelConfiguration?.requestHeaders,
-			zeroDataRetentionEnabled: modelConfiguration?.zeroDataRetentionEnabled
+			zeroDataRetentionEnabled: modelConfiguration?.zeroDataRetentionEnabled,
+			editTools: modelConfiguration?.editTools
 		};
 		const modelInfo = resolveModelInfo(model.id, this._name, undefined, modelCapabilities);
 		if (modelCapabilities?.url?.includes('/responses')) {
diff --git a/src/platform/endpoint/common/endpointProvider.ts b/src/platform/endpoint/common/endpointProvider.ts
index e903a2b6..470d3512 100644
--- a/src/platform/endpoint/common/endpointProvider.ts
+++ b/src/platform/endpoint/common/endpointProvider.ts
@@ -96,6 +96,7 @@ export type IChatModelInformation = IModelAPIResponse & {
 	urlOrRequestMetadata?: string | RequestMetadata;
 	requestHeaders?: Readonly<Record<string, string>>;
 	zeroDataRetentionEnabled?: boolean;
+	editTools?: readonly EndpointEditToolName[];
 };
 
 export function isChatModelInformation(model: IModelAPIResponse): model is IChatModelInformation {
diff --git a/src/platform/endpoint/node/chatEndpoint.ts b/src/platform/endpoint/node/chatEndpoint.ts
index e0f9eb49..77bf5db0 100644
--- a/src/platform/endpoint/node/chatEndpoint.ts
+++ b/src/platform/endpoint/node/chatEndpoint.ts
@@ -31,7 +31,7 @@ import { ITokenizerProvider } from '../../tokenizer/node/tokenizer';
 import { ICAPIClientService } from '../common/capiClient';
 import { isAnthropicFamily, isGeminiFamily } from '../common/chatModelCapabilities';
 import { IDomainService } from '../common/domainService';
-import { CustomModel, IChatModelInformation, ModelSupportedEndpoint } from '../common/endpointProvider';
+import { CustomModel, EndpointEditToolName, IChatModelInformation, ModelSupportedEndpoint } from '../common/endpointProvider';
 import { createMessagesRequestBody, processResponseFromMessagesEndpoint } from './messagesApi';
 import { createResponsesRequestBody, processResponseFromChatEndpoint } from './responsesApi';
 
@@ -131,6 +131,7 @@ export class ChatEndpoint implements IChatEndpoint {
 	public readonly restrictedToSkus?: string[] | undefined;
 	public readonly customModel?: CustomModel | undefined;
 	public readonly maxPromptImages?: number | undefined;
+	public readonly supportedEditTools?: readonly EndpointEditToolName[] | undefined;
 
 	private readonly _supportsStreaming: boolean;
 
@@ -167,6 +168,7 @@ export class ChatEndpoint implements IChatEndpoint {
 		this._supportsStreaming = !!modelMetadata.capabilities.supports.streaming;
 		this.customModel = modelMetadata.custom_model;
 		this.maxPromptImages = modelMetadata.capabilities.limits?.vision?.max_prompt_images;
+		this.supportedEditTools = modelMetadata.editTools;
 	}
 
 	public getExtraHeaders(location?: ChatLocation): Record<string, string> {

I built a local extension incorporating this code fix, and it works as expected.

Therefore, we would like to request an official fix to properly support the editTools configuration for custom models.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions