豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit 80cb675

Browse files
authored
Refactor enableThinking/reasoningEffort into IModelCapabilityOptions (#308387)
* Refactor enableThinking/reasoningEffort into IModelCapabilityOptions * Strip reasoningEffort from search/execution subagent loops * Fix stale comment referencing options.enableThinking
1 parent 884e76f commit 80cb675

File tree

16 files changed

+125
-104
lines changed

16 files changed

+125
-104
lines changed

extensions/copilot/src/extension/chatSessions/claude/node/claudeLanguageModelServer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ export class ClaudeLanguageModelServer extends Disposable {
229229
messages: messagesForLogging,
230230
finishedCb: async () => undefined,
231231
location: ChatLocation.MessagesProxy,
232-
enableThinking: true,
232+
modelCapabilities: { enableThinking: true },
233233
userInitiatedRequest: isUserInitiatedMessage
234234
}, tokenSource.token);
235235

extensions/copilot/src/extension/conversation/vscode-node/languageModelAccess.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,9 @@ export class CopilotLanguageModelWrapper extends Disposable {
626626
requestOptions: options,
627627
userInitiatedRequest: !!extensionId,
628628
telemetryProperties,
629-
reasoningEffort: typeof _options.modelConfiguration?.reasoningEffort === 'string' ? _options.modelConfiguration.reasoningEffort : undefined,
629+
modelCapabilities: {
630+
reasoningEffort: typeof _options.modelConfiguration?.reasoningEffort === 'string' ? _options.modelConfiguration.reasoningEffort : undefined,
631+
},
630632
}, token);
631633

632634
// Run request within the parent OTel context (no extra span) so chat spans in chatMLFetcher inherit the agent trace

extensions/copilot/src/extension/externalAgents/node/oaiLanguageModelServer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ export class OpenAILanguageModelServer extends Disposable {
205205
messages: messagesForLogging,
206206
finishedCb: async () => undefined,
207207
location: ChatLocation.ResponsesProxy,
208-
enableThinking: true,
208+
modelCapabilities: { enableThinking: true },
209209
userInitiatedRequest: isUserInitiatedMessage
210210
}, tokenSource.token);
211211

extensions/copilot/src/extension/intents/node/toolCallingLoop.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export interface IToolCallingBuiltPromptEvent {
103103
tools: LanguageModelToolInformation[];
104104
}
105105

106-
export type ToolCallingLoopFetchOptions = Required<Pick<IMakeChatRequestOptions, 'messages' | 'finishedCb' | 'requestOptions' | 'userInitiatedRequest' | 'turnId'>> & Pick<IMakeChatRequestOptions, 'enableThinking' | 'reasoningEffort'>;
106+
export type ToolCallingLoopFetchOptions = Required<Pick<IMakeChatRequestOptions, 'messages' | 'finishedCb' | 'requestOptions' | 'userInitiatedRequest' | 'turnId'>> & Pick<IMakeChatRequestOptions, 'modelCapabilities'>;
107107

108108
interface StartHookResult {
109109
/**
@@ -1417,8 +1417,6 @@ export abstract class ToolCallingLoop<TOptions extends IToolCallingLoopOptions =
14171417
let statefulMarker: string | undefined;
14181418
const toolCalls: IToolCall[] = [];
14191419
let thinkingItem: ThinkingDataItem | undefined;
1420-
const rawEffort = this.options.request.modelConfiguration?.reasoningEffort;
1421-
const reasoningEffort = typeof rawEffort === 'string' ? rawEffort : undefined;
14221420
const shouldDisableThinking = isContinuation && isAnthropicFamily(endpoint) && !ToolCallingLoop.messagesContainThinking(effectiveBuildPromptResult.messages);
14231421
const enableThinking = !shouldDisableThinking;
14241422
let phase: string | undefined;
@@ -1470,8 +1468,9 @@ export abstract class ToolCallingLoop<TOptions extends IToolCallingLoopOptions =
14701468
})),
14711469
},
14721470
userInitiatedRequest: (iterationNumber === 0 && !isContinuation && !this.options.request.subAgentInvocationId && !this.options.request.isSystemInitiated) || this.stopHookUserInitiated,
1473-
enableThinking,
1474-
reasoningEffort,
1471+
modelCapabilities: {
1472+
enableThinking,
1473+
},
14751474
}, token).finally(() => {
14761475
this.stopHookUserInitiated = false;
14771476
});

extensions/copilot/src/extension/prompt/node/defaultIntentRequestHandler.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { IGitService } from '../../../platform/git/common/gitService';
2121
import { IOctoKitService } from '../../../platform/github/common/githubService';
2222
import { HAS_IGNORED_FILES_MESSAGE } from '../../../platform/ignore/common/ignoreService';
2323
import { ILogService } from '../../../platform/log/common/logService';
24-
import { isAnthropicToolSearchEnabled } from '../../../platform/networking/common/anthropic';
24+
import { isAnthropicContextEditingEnabled, isAnthropicToolSearchEnabled } from '../../../platform/networking/common/anthropic';
2525
import { FilterReason } from '../../../platform/networking/common/openai';
2626
import { IOTelService } from '../../../platform/otel/common/otelService';
2727
import { CapturingToken } from '../../../platform/requestLogger/common/capturingToken';
@@ -693,9 +693,18 @@ class DefaultToolCallingLoop extends ToolCallingLoop<IDefaultToolLoopOptions> {
693693
const debugName = this._isInlineSummarizationRequest ? 'inlineSummarizeConversationHistory-full' : baseDebugName;
694694
const location = this.options.overrideRequestLocation ?? this.options.location;
695695
const isThinkingLocation = location === ChatLocation.Agent || location === ChatLocation.MessagesProxy;
696+
const rawEffort = this.options.request.modelConfiguration?.reasoningEffort;
697+
const reasoningEffort = typeof rawEffort === 'string' ? rawEffort : undefined;
698+
const isSubagent = !!this.options.request.subAgentInvocationId;
696699
return this.options.invocation.endpoint.makeChatRequest2({
697700
...opts,
698-
enableThinking: isThinkingLocation && opts.enableThinking,
701+
modelCapabilities: {
702+
...opts.modelCapabilities,
703+
enableThinking: isThinkingLocation && opts.modelCapabilities?.enableThinking,
704+
reasoningEffort,
705+
enableToolSearch: !isSubagent && isAnthropicToolSearchEnabled(this.options.invocation.endpoint, this._configurationService),
706+
enableContextEditing: !isSubagent && isAnthropicContextEditingEnabled(this.options.invocation.endpoint, this._configurationService, this._experimentationService),
707+
},
699708
debugName,
700709
conversationId: this.options.conversation.sessionId,
701710
turnId: opts.turnId,

extensions/copilot/src/extension/prompt/node/executionSubagentToolCallingLoop.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,14 @@ export class ExecutionSubagentToolCallingLoop extends ToolCallingLoop<IExecution
125125
return allTools.filter(tool => allowedExecutionTools.has(tool.name as ToolName));
126126
}
127127

128-
protected async fetch({ messages, finishedCb, requestOptions, enableThinking, reasoningEffort }: ToolCallingLoopFetchOptions, token: CancellationToken): Promise<ChatResponse> {
128+
protected async fetch({ messages, finishedCb, requestOptions, modelCapabilities }: ToolCallingLoopFetchOptions, token: CancellationToken): Promise<ChatResponse> {
129129
const endpoint = await this.getEndpoint();
130130
return endpoint.makeChatRequest2({
131131
debugName: ExecutionSubagentToolCallingLoop.ID,
132132
messages,
133133
finishedCb,
134134
location: this.options.location,
135-
enableThinking,
136-
reasoningEffort,
135+
modelCapabilities: { ...modelCapabilities, reasoningEffort: undefined },
137136
requestOptions: {
138137
...(requestOptions ?? {}),
139138
temperature: 0

extensions/copilot/src/extension/prompt/node/searchSubagentToolCallingLoop.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,15 +139,14 @@ export class SearchSubagentToolCallingLoop extends ToolCallingLoop<ISearchSubage
139139
return allTools.filter(tool => allowedSearchTools.has(tool.name as ToolName));
140140
}
141141

142-
protected async fetch({ messages, finishedCb, requestOptions, enableThinking, reasoningEffort }: ToolCallingLoopFetchOptions, token: CancellationToken): Promise<ChatResponse> {
142+
protected async fetch({ messages, finishedCb, requestOptions, modelCapabilities }: ToolCallingLoopFetchOptions, token: CancellationToken): Promise<ChatResponse> {
143143
const endpoint = await this.getEndpoint();
144144
return endpoint.makeChatRequest2({
145145
debugName: SearchSubagentToolCallingLoop.ID,
146146
messages,
147147
finishedCb,
148148
location: this.options.location,
149-
enableThinking,
150-
reasoningEffort,
149+
modelCapabilities: { ...modelCapabilities, reasoningEffort: undefined },
151150
requestOptions: {
152151
...requestOptions,
153152
temperature: 0

extensions/copilot/src/extension/tools/node/toolSearchTool.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import type * as vscode from 'vscode';
7+
import { TOOL_SEARCH_SUPPORTED_MODELS } from '../../../platform/endpoint/common/chatModelCapabilities';
78
import { ILogService } from '../../../platform/log/common/logService';
8-
import { CUSTOM_TOOL_SEARCH_NAME, TOOL_SEARCH_SUPPORTED_MODELS } from '../../../platform/networking/common/anthropic';
9+
import { CUSTOM_TOOL_SEARCH_NAME } from '../../../platform/networking/common/anthropic';
910
import { LanguageModelTextPart, LanguageModelToolResult } from '../../../vscodeTypes';
1011
import { ICopilotModelSpecificTool, ToolRegistry } from '../common/toolsRegistry';
1112
import { IToolsService } from '../common/toolsService';

extensions/copilot/src/platform/endpoint/common/chatModelCapabilities.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,3 +379,47 @@ export function getVerbosityForModelSync(model: IChatEndpoint): 'low' | 'medium'
379379

380380
return undefined;
381381
}
382+
383+
/** Model ID prefixes that support the tool search tool. */
384+
export const TOOL_SEARCH_SUPPORTED_MODELS = [
385+
'claude-sonnet-4.5',
386+
'claude-sonnet-4.6',
387+
'claude-opus-4.5',
388+
'claude-opus-4.6',
389+
] as const;
390+
391+
/**
392+
* Returns true if the model supports the tool search tool.
393+
* Provider-agnostic: add additional model prefixes here as other providers adopt tool search.
394+
*/
395+
export function modelSupportsToolSearch(modelId: string): boolean {
396+
return TOOL_SEARCH_SUPPORTED_MODELS.some(prefix => modelId.toLowerCase().startsWith(prefix));
397+
}
398+
399+
/**
400+
* Context editing is supported by:
401+
* - Claude Haiku 4.5 (claude-haiku-4-5-* or claude-haiku-4.5-*)
402+
* - Claude Sonnet 4.6 (claude-sonnet-4-6-* or claude-sonnet-4.6-*)
403+
* - Claude Sonnet 4.5 (claude-sonnet-4-5-* or claude-sonnet-4.5-*)
404+
* - Claude Sonnet 4 (claude-sonnet-4-*)
405+
* - Claude Opus 4.6 (claude-opus-4-6-* or claude-opus-4.6-*)
406+
* - Claude Opus 4.5 (claude-opus-4-5-* or claude-opus-4.5-*)
407+
* - Claude Opus 4.1 (claude-opus-4-1-* or claude-opus-4.1-*)
408+
* - Claude Opus 4 (claude-opus-4-*)
409+
* Provider-agnostic: add additional model prefixes here as other providers adopt context editing.
410+
*/
411+
export function modelSupportsContextEditing(modelId: string): boolean {
412+
const normalized = modelId.toLowerCase().replace(/\./g, '-');
413+
// The 1M context variant doesn't need context editing
414+
if (normalized.includes('1m')) {
415+
return false;
416+
}
417+
return normalized.startsWith('claude-haiku-4-5') ||
418+
normalized.startsWith('claude-sonnet-4-6') ||
419+
normalized.startsWith('claude-sonnet-4-5') ||
420+
normalized.startsWith('claude-sonnet-4') ||
421+
normalized.startsWith('claude-opus-4-6') ||
422+
normalized.startsWith('claude-opus-4-5') ||
423+
normalized.startsWith('claude-opus-4-1') ||
424+
normalized.startsWith('claude-opus-4');
425+
}

extensions/copilot/src/platform/endpoint/common/endpointProvider.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ export type IChatModelCapabilities = {
5454
max_thinking_budget?: number;
5555
min_thinking_budget?: number;
5656
reasoning_effort?: string[];
57+
tool_search?: boolean;
58+
context_editing?: boolean;
5759
};
5860
};
5961

0 commit comments

Comments
 (0)