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