Skip to content

Commit 6809989

Browse files
authored
fix(provider): disable thinking for internal helper requests (#137)
1 parent 4719d73 commit 6809989

9 files changed

Lines changed: 93 additions & 32 deletions

File tree

src/provider/debug/diagnostics.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@ import { getDebugLoggingEnabled } from '../../config';
44
import { LANGUAGE_MODEL_CHAT_SYSTEM_ROLE } from '../../consts';
55
import { logger } from '../../logger';
66
import type { DeepSeekMessage, DeepSeekRequest, DeepSeekTool, DeepSeekUsage } from '../../types';
7+
import {
8+
classifyDeepSeekRequest,
9+
formatModelFields,
10+
formatRequestLogLine,
11+
type RequestKind,
12+
} from '../routing';
713
import { REPLAY_MARKER_MIME, parseFirstReplayMarker } from '../replay';
814
import type { ConversationSegment } from '../segment';
915
import { ACTIVATE_TOOL_PREFIX } from '../tools/consts';
1016
import type { ActivatePreflightInspection } from '../tools/preflight';
1117
import { IMAGE_DESCRIPTION_UNAVAILABLE } from '../vision/consts';
1218
import type { VisionProxySource, VisionResolutionStats as VisionPipelineStats } from '../vision';
13-
import {
14-
classifyDeepSeekRequest,
15-
formatModelFields,
16-
formatRequestLogLine,
17-
type RequestKind,
18-
} from './classifier';
1919

2020
const LARGE_MESSAGE_CHARS = 10_000;
2121
const HASH_WINDOW_CHARS = 2_048;

src/provider/debug/dump.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,17 @@ import { LANGUAGE_MODEL_CHAT_SYSTEM_ROLE } from '../../consts';
88
import { safeStringify, toWellFormedString } from '../../json';
99
import { logger } from '../../logger';
1010
import type { DeepSeekMessage, DeepSeekRequest } from '../../types';
11-
import { parseReplayMarkerData, REPLAY_MARKER_MIME } from '../replay';
12-
import type { ConversationSegment } from '../segment';
13-
import { ACTIVATE_TOOL_PREFIX } from '../tools/consts';
14-
import type { VisionProxySource, VisionResolutionStats } from '../vision';
1511
import {
1612
classifyDeepSeekRequest,
1713
classifyProviderRequest,
1814
formatModelFields,
1915
formatRequestLogLine,
2016
type RequestKind,
21-
} from './classifier';
17+
} from '../routing';
18+
import { parseReplayMarkerData, REPLAY_MARKER_MIME } from '../replay';
19+
import type { ConversationSegment } from '../segment';
20+
import { ACTIVATE_TOOL_PREFIX } from '../tools/consts';
21+
import type { VisionProxySource, VisionResolutionStats } from '../vision';
2222

2323
let dumpCounter = 0;
2424
let providerInputDumpCounter = 0;

src/provider/debug/index.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,3 @@ export type {
99
ReplayMarkerReportTrigger,
1010
} from './diagnostics';
1111
export { dumpDeepSeekRequest, dumpProviderInput, ensureRequestDumpRoot } from './dump';
12-
export {
13-
classifyDeepSeekRequest,
14-
classifyProviderRequest,
15-
formatRequestLogLine,
16-
type RequestKind,
17-
} from './classifier';

src/provider/index.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,11 @@ import { getStabilizeToolListEnabled } from '../config';
44
import { MODELS } from '../consts';
55
import { t } from '../i18n';
66
import { logger } from '../logger';
7-
import {
8-
classifyProviderRequest,
9-
createCacheDiagnosticsRecorder,
10-
dumpProviderInput,
11-
} from './debug';
7+
import { createCacheDiagnosticsRecorder, dumpProviderInput } from './debug';
128
import { toChatInfo } from './models';
139
import { BalanceCurrencyResolver } from './pricing/currency';
1410
import { prepareChatRequest } from './request';
11+
import { classifyProviderRequest } from './routing';
1512
import { resolveConversationSegment } from './segment';
1613
import { streamChatCompletion } from './stream';
1714
import { estimateTokenCount } from './tokens';

src/provider/request.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@ import { t } from '../i18n';
77
import type { DeepSeekRequest } from '../types';
88
import { convertMessages, countMessageChars } from './convert';
99
import {
10-
classifyDeepSeekRequest,
1110
dumpDeepSeekRequest,
1211
type CacheDiagnosticsRecorder,
1312
type CacheDiagnosticsRun,
14-
type RequestKind,
1513
} from './debug';
1614
import { getConfiguredThinkingEffort, type ModelConfigurationOptions } from './models';
15+
import { classifyDeepSeekRequest, shouldForceThinkingNone, type RequestKind } from './routing';
1716
import type { ReplayMarkerMetadata } from './replay';
1817
import type { ConversationSegment } from './segment';
1918
import { collectTrailingToolResultIds, prepareRequestTools } from './tools/request';
@@ -64,7 +63,6 @@ export async function prepareChatRequest({
6463
const client = new DeepSeekClient(getBaseUrl(), apiKey);
6564
const modelDef = MODELS.find((m) => m.id === modelInfo.id);
6665
const isThinkingModel = modelDef?.capabilities.thinking ?? false;
67-
const thinkingEffort = getConfiguredThinkingEffort(options as ModelConfigurationOptions);
6866
const maxTokens = getMaxTokens();
6967

7068
const visionResolution = await resolveImageMessages(messages, token, getVisionDescriber);
@@ -73,13 +71,24 @@ export async function prepareChatRequest({
7371
const tools = prepareRequestTools(modelDef?.capabilities.toolCalling, options);
7472

7573
const totalRequestChars = countMessageChars(deepseekMessages);
76-
const request: DeepSeekRequest = {
74+
const baseRequest: DeepSeekRequest = {
7775
model: getApiModelId(modelInfo.id),
7876
messages: deepseekMessages,
7977
stream: true,
8078
tools,
8179
tool_choice: tools && tools.length > 0 ? ('auto' as const) : undefined,
8280
max_tokens: maxTokens,
81+
};
82+
const requestKind = classifyDeepSeekRequest({
83+
request: baseRequest,
84+
inputMessages: messages,
85+
});
86+
const configuredThinkingEffort = getConfiguredThinkingEffort(
87+
options as ModelConfigurationOptions,
88+
);
89+
const thinkingEffort = shouldForceThinkingNone(requestKind) ? 'none' : configuredThinkingEffort;
90+
const request: DeepSeekRequest = {
91+
...baseRequest,
8392
...(isThinkingModel
8493
? {
8594
thinking: {
@@ -89,10 +98,6 @@ export async function prepareChatRequest({
8998
}
9099
: {}),
91100
};
92-
const requestKind = classifyDeepSeekRequest({
93-
request,
94-
inputMessages: messages,
95-
});
96101
dumpDeepSeekRequest(request, {
97102
globalStorageUri,
98103
segment,
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,41 @@ export type RequestKind =
66
| 'terminal-steering'
77
| 'todo-tracker'
88
| 'settings-resolver'
9+
| 'prompt-categorizer'
10+
| 'chat-title'
11+
| 'inline-progress-message'
12+
| 'git-branch-name'
13+
| 'git-commit-message'
14+
| 'rename-suggestions'
915
| 'background'
1016
| 'unknown';
1117

1218
const TODO_TRACKER_PREFIX = 'You are a background task tracker';
19+
const PROMPT_CATEGORIZER_PREFIX = 'You are an expert classifier for AI coding assistant prompts';
1320
const SETTINGS_RESOLVER_PREFIX =
1421
'You are a Visual Studio Code assistant. Your job is to assist users in using Visual Studio Code by returning settings';
22+
const CHAT_TITLE_PREFIXES = [
23+
'You are an expert in crafting ultra-compact titles',
24+
'You are an expert in crafting pithy titles',
25+
] as const;
26+
const INLINE_PROGRESS_MESSAGE_PREFIX =
27+
'You are an expert in writing short, catchy, and encouraging progress messages';
28+
const GIT_BRANCH_NAME_PREFIX = 'You are an expert in crafting pithy branch names';
29+
const GIT_COMMIT_MESSAGE_PREFIX =
30+
'You are an AI programming assistant, helping a software developer to come with the best git commit message';
31+
const RENAME_SUGGESTIONS_PREFIX = 'You are a distinguished software engineer';
1532
const MAIN_AGENT_PREFIX = 'You are an expert AI programming assistant';
1633
const TERMINAL_NOTIFICATION_PATTERN = /^\[Terminal\s+\S+\s+notification:/;
34+
const REQUEST_KINDS_WITH_FORCED_NONE_THINKING = new Set<RequestKind>([
35+
'todo-tracker',
36+
'prompt-categorizer',
37+
'settings-resolver',
38+
'chat-title',
39+
'inline-progress-message',
40+
'git-branch-name',
41+
'git-commit-message',
42+
'rename-suggestions',
43+
]);
1744

1845
export function formatModelFields(vscodeModelId: string, apiModelId?: string): string {
1946
const apiField = apiModelId && apiModelId !== vscodeModelId ? ` apiModel=${apiModelId}` : '';
@@ -24,6 +51,10 @@ export function formatRequestLogLine(requestKind: RequestKind, message: string):
2451
return `[${requestKind}] ${message}`;
2552
}
2653

54+
export function shouldForceThinkingNone(requestKind: RequestKind): boolean {
55+
return REQUEST_KINDS_WITH_FORCED_NONE_THINKING.has(requestKind);
56+
}
57+
2758
export function classifyProviderRequest(input: {
2859
messages: readonly vscode.LanguageModelChatRequestMessage[];
2960
tools?: readonly vscode.LanguageModelChatTool[];
@@ -66,9 +97,30 @@ function classifyRequest(input: {
6697
) {
6798
return 'todo-tracker';
6899
}
100+
if (
101+
isOnlyTool(input.toolNames, 'categorize_prompt') ||
102+
firstText.startsWith(PROMPT_CATEGORIZER_PREFIX)
103+
) {
104+
return 'prompt-categorizer';
105+
}
69106
if (firstText.startsWith(SETTINGS_RESOLVER_PREFIX)) {
70107
return 'settings-resolver';
71108
}
109+
if (startsWithAny(firstText, CHAT_TITLE_PREFIXES)) {
110+
return 'chat-title';
111+
}
112+
if (firstText.startsWith(INLINE_PROGRESS_MESSAGE_PREFIX)) {
113+
return 'inline-progress-message';
114+
}
115+
if (firstText.startsWith(GIT_BRANCH_NAME_PREFIX)) {
116+
return 'git-branch-name';
117+
}
118+
if (firstText.startsWith(GIT_COMMIT_MESSAGE_PREFIX)) {
119+
return 'git-commit-message';
120+
}
121+
if (firstText.startsWith(RENAME_SUGGESTIONS_PREFIX)) {
122+
return 'rename-suggestions';
123+
}
72124
if (
73125
firstText.startsWith(MAIN_AGENT_PREFIX) ||
74126
firstText.includes('<skills>') ||
@@ -86,6 +138,10 @@ function isOnlyTool(toolNames: readonly string[], toolName: string): boolean {
86138
return toolNames.length === 1 && toolNames[0] === toolName;
87139
}
88140

141+
function startsWithAny(text: string, prefixes: readonly string[]): boolean {
142+
return prefixes.some((prefix) => text.startsWith(prefix));
143+
}
144+
89145
function getDeepSeekToolName(tool: DeepSeekTool): string {
90146
return tool.function.name;
91147
}

src/provider/routing/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export {
2+
classifyDeepSeekRequest,
3+
classifyProviderRequest,
4+
formatModelFields,
5+
formatRequestLogLine,
6+
shouldForceThinkingNone,
7+
type RequestKind,
8+
} from './classifier';

src/provider/stream.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import { createUserFacingError } from '../client';
33
import { logger } from '../logger';
44
import type { DeepSeekToolCall, DeepSeekUsage } from '../types';
55
import {
6-
formatRequestLogLine,
76
observeCancellationToken,
87
type CacheDiagnosticsRun,
98
type ReplayMarkerReportTrigger,
109
} from './debug';
10+
import { formatRequestLogLine } from './routing';
1111
import {
1212
createReplayMarkerPart,
1313
hasReplayMarkerMetadata,

src/provider/tools/flow.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import vscode from 'vscode';
22
import { t } from '../../i18n';
3-
import { logToolFlowDiagnostics, type RequestKind } from '../debug';
3+
import { logToolFlowDiagnostics } from '../debug';
4+
import type { RequestKind } from '../routing';
45
import { ACTIVATE_TOOL_PREFIX, MAX_PREFLIGHT_ROUNDS_PER_USER_REQUEST } from './consts';
56
import { createToolDriftNotice, filterProviderNotices } from './notices';
67
import {

0 commit comments

Comments
 (0)