Skip to content

Commit 7212765

Browse files
authored
fix(diagnostics): classify cache traces by request kind (#97)
1 parent 792691d commit 7212765

9 files changed

Lines changed: 562 additions & 98 deletions

File tree

src/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { CONFIG_SECTION, WALKTHROUGH_ID, WELCOME_SHOWN_KEY } from './consts';
44
import { t } from './i18n';
55
import { logger } from './logger';
66
import { DeepSeekChatProvider } from './provider';
7-
import { ensureRequestDumpRoot } from './provider/dump';
7+
import { ensureRequestDumpRoot } from './provider/debug';
88

99
let activeProvider: DeepSeekChatProvider | undefined;
1010

src/provider/debug/classifier.ts

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import vscode from 'vscode';
2+
import type { DeepSeekRequest, DeepSeekTool } from '../../types';
3+
4+
export type RequestKind =
5+
| 'main-agent'
6+
| 'terminal-steering'
7+
| 'todo-tracker'
8+
| 'settings-resolver'
9+
| 'background'
10+
| 'unknown';
11+
12+
const TODO_TRACKER_PREFIX = 'You are a background task tracker';
13+
const SETTINGS_RESOLVER_PREFIX =
14+
'You are a Visual Studio Code assistant. Your job is to assist users in using Visual Studio Code by returning settings';
15+
const MAIN_AGENT_PREFIX = 'You are an expert AI programming assistant';
16+
const TERMINAL_NOTIFICATION_PATTERN = /^\[Terminal\s+\S+\s+notification:/;
17+
18+
export function formatModelFields(vscodeModelId: string, apiModelId?: string): string {
19+
const apiField = apiModelId && apiModelId !== vscodeModelId ? ` apiModel=${apiModelId}` : '';
20+
return `model=${vscodeModelId}${apiField}`;
21+
}
22+
23+
export function formatRequestLogLine(requestKind: RequestKind, message: string): string {
24+
return `[${requestKind}] ${message}`;
25+
}
26+
27+
export function classifyProviderRequest(input: {
28+
messages: readonly vscode.LanguageModelChatRequestMessage[];
29+
tools?: readonly vscode.LanguageModelChatTool[];
30+
}): RequestKind {
31+
return classifyRequest({
32+
firstText: getFirstVscodeText(input.messages),
33+
latestUserText: getLatestVscodeUserText(input.messages),
34+
toolNames: input.tools?.map((tool) => tool.name) ?? [],
35+
});
36+
}
37+
38+
export function classifyDeepSeekRequest(input: {
39+
request: DeepSeekRequest;
40+
inputMessages?: readonly vscode.LanguageModelChatRequestMessage[];
41+
}): RequestKind {
42+
return classifyRequest({
43+
firstText:
44+
input.request.messages[0]?.content ??
45+
(input.inputMessages ? getFirstVscodeText(input.inputMessages) : ''),
46+
latestUserText:
47+
(input.inputMessages ? getLatestVscodeUserText(input.inputMessages) : '') ||
48+
getLatestDeepSeekUserText(input.request),
49+
toolNames: input.request.tools?.map(getDeepSeekToolName) ?? [],
50+
});
51+
}
52+
53+
function classifyRequest(input: {
54+
firstText: string;
55+
latestUserText: string;
56+
toolNames: readonly string[];
57+
}): RequestKind {
58+
const firstText = input.firstText.trimStart();
59+
const latestUserText = input.latestUserText.trimStart();
60+
if (TERMINAL_NOTIFICATION_PATTERN.test(latestUserText)) {
61+
return 'terminal-steering';
62+
}
63+
if (
64+
isOnlyTool(input.toolNames, 'manage_todo_list') ||
65+
firstText.startsWith(TODO_TRACKER_PREFIX)
66+
) {
67+
return 'todo-tracker';
68+
}
69+
if (firstText.startsWith(SETTINGS_RESOLVER_PREFIX)) {
70+
return 'settings-resolver';
71+
}
72+
if (
73+
firstText.startsWith(MAIN_AGENT_PREFIX) ||
74+
firstText.includes('<skills>') ||
75+
firstText.includes('<agents>')
76+
) {
77+
return 'main-agent';
78+
}
79+
if (input.toolNames.length > 0 || firstText.length > 0) {
80+
return 'background';
81+
}
82+
return 'unknown';
83+
}
84+
85+
function isOnlyTool(toolNames: readonly string[], toolName: string): boolean {
86+
return toolNames.length === 1 && toolNames[0] === toolName;
87+
}
88+
89+
function getDeepSeekToolName(tool: DeepSeekTool): string {
90+
return tool.function.name;
91+
}
92+
93+
function getFirstVscodeText(messages: readonly vscode.LanguageModelChatRequestMessage[]): string {
94+
const firstMessage = messages[0];
95+
if (!firstMessage) {
96+
return '';
97+
}
98+
99+
return getVscodeMessageText(firstMessage);
100+
}
101+
102+
function getLatestVscodeUserText(
103+
messages: readonly vscode.LanguageModelChatRequestMessage[],
104+
): string {
105+
for (let index = messages.length - 1; index >= 0; index -= 1) {
106+
const message = messages[index];
107+
if (message.role === vscode.LanguageModelChatMessageRole.User) {
108+
return getVscodeMessageText(message);
109+
}
110+
}
111+
return '';
112+
}
113+
114+
function getVscodeMessageText(message: vscode.LanguageModelChatRequestMessage): string {
115+
let text = '';
116+
for (const part of message.content) {
117+
if (part instanceof vscode.LanguageModelTextPart) {
118+
text += part.value;
119+
}
120+
}
121+
return text;
122+
}
123+
124+
function getLatestDeepSeekUserText(request: DeepSeekRequest): string {
125+
for (let index = request.messages.length - 1; index >= 0; index -= 1) {
126+
const message = request.messages[index];
127+
if (message.role === 'user') {
128+
return message.content;
129+
}
130+
}
131+
return '';
132+
}

0 commit comments

Comments
 (0)