Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/chat/common/chatDebugService.ts
13401 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { Event } from '../../../../base/common/event.js';
7
import { IDisposable } from '../../../../base/common/lifecycle.js';
8
import { URI } from '../../../../base/common/uri.js';
9
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
10
import { CancellationToken } from '../../../../base/common/cancellation.js';
11
12
/**
13
* The severity level of a chat debug log event.
14
*/
15
export enum ChatDebugLogLevel {
16
Trace = 0,
17
Info = 1,
18
Warning = 2,
19
Error = 3
20
}
21
22
/**
23
* The result of a hook execution.
24
*/
25
export enum ChatDebugHookResult {
26
/** The hook executed successfully (exit code 0). */
27
Success = 0,
28
/** The hook returned a blocking error (exit code 2). */
29
Error = 1,
30
/** The hook returned a non-blocking warning (other non-zero exit codes). */
31
NonBlockingError = 2
32
}
33
34
/**
35
* Common properties shared by all chat debug event types.
36
*/
37
export interface IChatDebugEventCommon {
38
readonly id?: string;
39
readonly sessionResource: URI;
40
readonly created: Date;
41
readonly parentEventId?: string;
42
}
43
44
/**
45
* A tool call event in the chat debug log.
46
*/
47
export interface IChatDebugToolCallEvent extends IChatDebugEventCommon {
48
readonly kind: 'toolCall';
49
readonly toolName: string;
50
readonly toolCallId?: string;
51
readonly input?: string;
52
readonly output?: string;
53
readonly result?: 'success' | 'error';
54
readonly durationInMillis?: number;
55
}
56
57
/**
58
* A model turn event representing an LLM request/response.
59
*/
60
export interface IChatDebugModelTurnEvent extends IChatDebugEventCommon {
61
readonly kind: 'modelTurn';
62
readonly model?: string;
63
readonly requestName?: string;
64
readonly inputTokens?: number;
65
readonly outputTokens?: number;
66
readonly cachedTokens?: number;
67
readonly totalTokens?: number;
68
readonly durationInMillis?: number;
69
}
70
71
/**
72
* A generic log event for unstructured or miscellaneous messages.
73
*/
74
export interface IChatDebugGenericEvent extends IChatDebugEventCommon {
75
readonly kind: 'generic';
76
readonly name: string;
77
readonly details?: string;
78
readonly level: ChatDebugLogLevel;
79
readonly category?: string;
80
}
81
82
/**
83
* A subagent invocation event, representing a spawned sub-agent within a session.
84
*/
85
export interface IChatDebugSubagentInvocationEvent extends IChatDebugEventCommon {
86
readonly kind: 'subagentInvocation';
87
readonly agentName: string;
88
readonly description?: string;
89
readonly status?: 'running' | 'completed' | 'failed';
90
readonly durationInMillis?: number;
91
readonly toolCallCount?: number;
92
readonly modelTurnCount?: number;
93
}
94
95
/**
96
* A named section within a user message or agent response.
97
*/
98
export interface IChatDebugMessageSection {
99
readonly name: string;
100
readonly content: string;
101
}
102
103
/**
104
* A user message event, representing the full prompt sent by the user.
105
*/
106
export interface IChatDebugUserMessageEvent extends IChatDebugEventCommon {
107
readonly kind: 'userMessage';
108
readonly message: string;
109
readonly sections: readonly IChatDebugMessageSection[];
110
}
111
112
/**
113
* An agent response event, representing the agent's response.
114
*/
115
export interface IChatDebugAgentResponseEvent extends IChatDebugEventCommon {
116
readonly kind: 'agentResponse';
117
readonly message: string;
118
readonly sections: readonly IChatDebugMessageSection[];
119
}
120
121
/**
122
* Union of all internal chat debug event types.
123
*/
124
export type IChatDebugEvent = IChatDebugToolCallEvent | IChatDebugModelTurnEvent | IChatDebugGenericEvent | IChatDebugSubagentInvocationEvent | IChatDebugUserMessageEvent | IChatDebugAgentResponseEvent;
125
126
export const IChatDebugService = createDecorator<IChatDebugService>('chatDebugService');
127
128
/**
129
* Service for collecting and exposing chat debug events.
130
* Internal components can log events,
131
* and the debug editor pane can display them.
132
*/
133
export interface IChatDebugService extends IDisposable {
134
readonly _serviceBrand: undefined;
135
136
/**
137
* Fired when a new event is added.
138
*/
139
readonly onDidAddEvent: Event<IChatDebugEvent>;
140
141
/**
142
* Fired when provider events are cleared for a session (before re-invoking providers).
143
*/
144
readonly onDidClearProviderEvents: Event<URI>;
145
146
/**
147
* Log a generic event to the debug service.
148
*/
149
log(sessionResource: URI, name: string, details?: string, level?: ChatDebugLogLevel, options?: { id?: string; category?: string; parentEventId?: string }): void;
150
151
/**
152
* Add a typed event to the debug service.
153
*/
154
addEvent(event: IChatDebugEvent): void;
155
156
/**
157
* Add an event sourced from an external provider.
158
* These events are cleared before re-invoking providers to avoid duplicates.
159
*/
160
addProviderEvent(event: IChatDebugEvent): void;
161
162
/**
163
* Get all events for a specific session.
164
*/
165
getEvents(sessionResource?: URI): readonly IChatDebugEvent[];
166
167
/**
168
* Get all session resources that have logged events.
169
*/
170
getSessionResources(): readonly URI[];
171
172
/**
173
* The currently active session resource for debugging.
174
*/
175
activeSessionResource: URI | undefined;
176
177
/**
178
* Clear all logged events.
179
*/
180
clear(): void;
181
182
/**
183
* Register an external provider that can supply additional debug events.
184
* This is used by the extension API (ChatDebugLogProvider).
185
*/
186
registerProvider(provider: IChatDebugLogProvider): IDisposable;
187
188
/**
189
* Check whether providers have already been invoked for a given session.
190
*/
191
hasInvokedProviders(sessionResource: URI): boolean;
192
193
/**
194
* Invoke all registered providers for a given session resource.
195
* Called when the Debug View is opened to fetch events from extensions.
196
*/
197
invokeProviders(sessionResource: URI): Promise<void>;
198
199
/**
200
* End a debug session: cancels any in-flight provider invocation,
201
* disposes the associated CancellationTokenSource, and removes it.
202
* Called when the chat session is disposed/archived.
203
*/
204
endSession(sessionResource: URI): void;
205
206
/**
207
* Resolve the full details of an event by its id.
208
* Delegates to the registered provider's resolveChatDebugLogEvent.
209
*/
210
resolveEvent(eventId: string): Promise<IChatDebugResolvedEventContent | undefined>;
211
212
/**
213
/**
214
* Export the debug log for a session via the registered provider.
215
*/
216
exportLog(sessionResource: URI): Promise<Uint8Array | undefined>;
217
218
/**
219
* Import a previously exported debug log via the registered provider.
220
* Returns the session URI for the imported data.
221
*/
222
importLog(data: Uint8Array): Promise<URI | undefined>;
223
224
/**
225
* Returns true if the event was logged by VS Code core
226
* (not sourced from an external provider).
227
*/
228
isCoreEvent(event: IChatDebugEvent): boolean;
229
230
/**
231
* Store a human-readable title for an imported session.
232
*/
233
setImportedSessionTitle(sessionResource: URI, title: string): void;
234
235
/**
236
* Get the stored title for an imported session, if available.
237
*/
238
getImportedSessionTitle(sessionResource: URI): string | undefined;
239
240
/**
241
* Fired when available session resources change (e.g. historical sessions discovered from disk).
242
*/
243
readonly onDidChangeAvailableSessionResources: Event<void>;
244
245
/**
246
* Store session resources that have debug log data available on disk.
247
* Called by the main thread after the extension reports historical sessions.
248
*/
249
addAvailableSessionResources(resources: readonly { uri: URI; title?: string }[]): void;
250
251
/**
252
* Get all session resources that have debug log data available,
253
* including historical sessions persisted on disk by the provider.
254
* Triggers a lazy fetch from the registered fetcher on first call.
255
*/
256
getAvailableSessionResources(): readonly URI[];
257
258
/**
259
* Register a callback that fetches available session resources from a provider.
260
* Called lazily when `getAvailableSessionResources()` is first invoked.
261
*/
262
registerAvailableSessionsFetcher(fetcher: (token: CancellationToken) => Promise<{ uri: URI; title?: string }[]>): void;
263
264
/**
265
* Get the stored title for a historical session discovered from disk.
266
*/
267
getHistoricalSessionTitle(sessionResource: URI): string | undefined;
268
269
}
270
271
/**
272
* Plain text content for a resolved debug event.
273
*/
274
export interface IChatDebugEventTextContent {
275
readonly kind: 'text';
276
readonly value: string;
277
}
278
279
/**
280
* The status of a file in a file list content.
281
*/
282
export type ChatDebugFileStatus = 'loaded' | 'skipped';
283
284
/**
285
* A single file entry in a file list content.
286
*/
287
export interface IChatDebugFileEntry {
288
readonly uri: URI;
289
readonly name?: string;
290
readonly status: ChatDebugFileStatus;
291
readonly storage?: string;
292
readonly extensionId?: string;
293
readonly skipReason?: string;
294
readonly errorMessage?: string;
295
readonly duplicateOf?: URI;
296
}
297
298
/**
299
* A source folder entry in a file list content.
300
*/
301
export interface IChatDebugSourceFolderEntry {
302
readonly uri: URI;
303
readonly storage: string;
304
}
305
306
/**
307
* Structured file list content for a resolved debug event.
308
* Contains resolved files and skipped/failed paths for rich rendering.
309
*/
310
export interface IChatDebugEventFileListContent {
311
readonly kind: 'fileList';
312
readonly discoveryType: string;
313
readonly durationInMillis: number;
314
readonly files: readonly IChatDebugFileEntry[];
315
readonly sourceFolders?: readonly IChatDebugSourceFolderEntry[];
316
}
317
318
/**
319
* Structured message content for a resolved debug event,
320
* containing collapsible sections.
321
*/
322
export interface IChatDebugEventMessageContent {
323
readonly kind: 'message';
324
readonly type: 'user' | 'agent';
325
readonly message: string;
326
readonly sections: readonly IChatDebugMessageSection[];
327
}
328
329
/**
330
* Structured tool call content for a resolved debug event.
331
* Contains the tool name, status, arguments, and output for rich rendering.
332
*/
333
export interface IChatDebugEventToolCallContent {
334
readonly kind: 'toolCall';
335
readonly toolName: string;
336
readonly result?: 'success' | 'error';
337
readonly durationInMillis?: number;
338
readonly input?: string;
339
readonly output?: string;
340
}
341
342
/**
343
* Structured model turn content for a resolved debug event.
344
* Contains request metadata, token usage, and timing for rich rendering.
345
*/
346
export interface IChatDebugEventModelTurnContent {
347
readonly kind: 'modelTurn';
348
readonly requestName: string;
349
readonly model?: string;
350
readonly status?: string;
351
readonly durationInMillis?: number;
352
readonly timeToFirstTokenInMillis?: number;
353
readonly maxInputTokens?: number;
354
readonly maxOutputTokens?: number;
355
readonly inputTokens?: number;
356
readonly outputTokens?: number;
357
readonly cachedTokens?: number;
358
readonly totalTokens?: number;
359
readonly errorMessage?: string;
360
readonly sections?: readonly IChatDebugMessageSection[];
361
}
362
363
/**
364
* Structured hook execution content for a resolved debug event.
365
* Contains the hook type, command, input, output, and result for rich rendering.
366
*/
367
export interface IChatDebugEventHookContent {
368
readonly kind: 'hook';
369
readonly hookType: string;
370
readonly command?: string;
371
readonly result?: ChatDebugHookResult;
372
readonly durationInMillis?: number;
373
readonly input?: string;
374
readonly output?: string;
375
readonly exitCode?: number;
376
readonly errorMessage?: string;
377
}
378
379
/**
380
* A single entry in the customization resolution log.
381
*/
382
export interface IChatDebugCustomizationLogEntry {
383
readonly category: 'applying' | 'skipped' | 'referenced' | 'skill' | 'custom-agent' | 'hook';
384
readonly name: string;
385
readonly uri?: URI;
386
readonly reason?: string;
387
}
388
389
/**
390
* Structured customization summary content for a resolved debug event.
391
* Contains per-file resolution logs showing how applyTo patterns, agent
392
* instructions, and referenced files were resolved by the instructions
393
* context computer.
394
*/
395
export interface IChatDebugEventCustomizationSummaryContent {
396
readonly kind: 'customizationSummary';
397
/** Per-file resolution detail entries. */
398
readonly resolutionLogs: readonly IChatDebugCustomizationLogEntry[];
399
/** Total wall-clock time of the collect() call in milliseconds. */
400
readonly durationInMillis: number;
401
/** Counts by type for the summary header. */
402
readonly counts: {
403
readonly instructions: number;
404
readonly skills: number;
405
readonly agents: number;
406
readonly hooks: number;
407
readonly skipped: number;
408
};
409
}
410
411
/**
412
* Union of all resolved event content types.
413
*/
414
export type IChatDebugResolvedEventContent = IChatDebugEventTextContent | IChatDebugEventFileListContent | IChatDebugEventMessageContent | IChatDebugEventToolCallContent | IChatDebugEventModelTurnContent | IChatDebugEventHookContent | IChatDebugEventCustomizationSummaryContent;
415
416
/**
417
* Provider interface for debug events.
418
*/
419
export interface IChatDebugLogProvider {
420
provideChatDebugLog(sessionResource: URI, token: CancellationToken): Promise<IChatDebugEvent[] | undefined>;
421
resolveChatDebugLogEvent?(eventId: string, token: CancellationToken): Promise<IChatDebugResolvedEventContent | undefined>;
422
provideChatDebugLogExport?(sessionResource: URI, token: CancellationToken): Promise<Uint8Array | undefined>;
423
resolveChatDebugLogImport?(data: Uint8Array, token: CancellationToken): Promise<URI | undefined>;
424
}
425
426