import { Disposable } from "@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle"; import { URI } from "@codingame/monaco-vscode-api/vscode/vs/base/common/uri"; import { IConfigurationService } from "@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration.service"; import { IFileService } from "@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service"; import { ILogService } from "@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service"; import { IAgentHostService } from "@codingame/monaco-vscode-api/vscode/vs/platform/agentHost/common/agentService.service"; import { IRemoteAgentHostService } from "@codingame/monaco-vscode-api/vscode/vs/platform/agentHost/common/remoteAgentHostService.service"; import { IWorkbenchContribution } from "@codingame/monaco-vscode-api/vscode/vs/workbench/common/contributions"; import { IPathService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/path/common/pathService.service"; import { IChatDebugEvent, IChatDebugResolvedEventContent } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/chatDebugService"; import { IChatDebugService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/chatDebugService.service"; /** * One record in an Agent Host Copilot CLI `events.jsonl` stream. The CLI * writes a line-delimited JSON log of the session under * `~/.copilot/session-state//events.jsonl`. Every record shares the same * envelope. Note that `parentId` is **not** a logical parent: the SDK defines * it as the chronologically preceding event in the session (a flat linked chain * over every event), not the user → model-turn → tool-call hierarchy. The * panel's trajectory tree is instead reconstructed from each record's logical * context (turn / tool-call / agent ids); see * {@link convertAgentHostEventsToDebugEvents}. */ interface IAgentHostEventRecord { readonly type: string; readonly id: string; readonly parentId: string | null; /** Sub-agent instance id; absent for the main agent and session-level events. */ readonly agentId?: string; readonly timestamp: string; readonly data: Record; } /** * Feeds Agent Host (Copilot CLI) sessions into the Agent Debug Logs panel by * reading each session's on-disk `events.jsonl` and converting the records * into {@link IChatDebugEvent}s. Registers a core-side * {@link IChatDebugLogProvider} (the service supports multiple providers * alongside the extension's), and adds discovered local sessions to the * available-sessions list so they appear in the home view. */ export declare class AgentHostChatDebugContribution extends Disposable implements IWorkbenchContribution { private readonly _chatDebugService; private readonly _fileService; private readonly _pathService; private readonly _remoteAgentHostService; private readonly _agentHostService; private readonly _configurationService; private readonly _logService; static readonly ID = "workbench.contrib.agentHostChatDebug"; /** Resolved (expanded) detail for each emitted event id. */ private readonly _resolved; /** Guards against concurrent/overlapping session discovery scans. */ private _discovering; /** Watches the currently-viewed session's events.jsonl for live refresh. */ private readonly _liveRefresh; private _watchedSessionKey; constructor(_chatDebugService: IChatDebugService, _fileService: IFileService, _pathService: IPathService, _remoteAgentHostService: IRemoteAgentHostService, _agentHostService: IAgentHostService, _configurationService: IConfigurationService, _logService: ILogService); /** * Runs {@link _discoverLocalSessions} when file logging is enabled, * guarding against overlapping scans. Safe to call repeatedly: * {@link IChatDebugService.addAvailableSessionResources} dedupes by URI. */ private _maybeDiscoverLocalSessions; private _resolveEventsUri; /** * Watches the given session's events.jsonl and re-invokes providers when it * changes, so the panel updates as new turns/requests stream in. Only one * session (the one currently shown) is watched at a time. Remote * (non-`file`) sessions are not watched; they still load on open. */ private _ensureLiveRefresh; /** * Returns the live AHP chat-state subscription for a local Agent Host * session, if one is currently active (i.e. the session is open/subscribed). * Turns (and their usage) live on the session's default chat channel, so we * subscribe to that channel rather than the session. Read-only: never * creates a subscription. */ private _sessionChatSubscription; /** * Reads live Copilot AIU from the AHP session state as a fallback usage * source for in-progress sessions (no `session.shutdown` summary yet). * Only AIU is reliable live; input/cache need the shutdown summary (F1). */ private _getLiveUsageTotals; private _provideChatDebugLog; private _discoverLocalSessions; } /** * Converts a parsed `events.jsonl` record stream into debug-panel events plus * their expanded detail. Pure (no services) so it can be unit-tested directly. * * The record `parentId` is **not** a logical parent: the Copilot SDK documents * it as "the chronologically preceding event in the session, forming a linked * chain" — a flat back-pointer over every event, not the user → model-turn → * tool-call hierarchy the panel's flow chart needs. So we reconstruct that * hierarchy from each record's logical context as we iterate chronologically: * - `session.start` is the tree root. * - a `user.message` hangs off the session root. * - an `assistant.message` hangs off the current user message (tracked per * agent), unless it carries a `parentToolCallId` (a sub-agent turn), in * which case it hangs off that spawning tool call. * - a `tool.execution_start` hangs off the current assistant message (tracked * per agent), unless it carries a `parentToolCallId` (a nested / sub-agent * tool), in which case it hangs off that parent tool call. * `tool.execution_start` and `tool.execution_complete` records share a * `toolCallId` and are merged into a single tool-call event. */ export declare function convertAgentHostEventsToDebugEvents(records: readonly IAgentHostEventRecord[], sessionResource: URI, fallbackUsageTotals?: ISessionUsageTotals): { readonly events: IChatDebugEvent[]; readonly resolved: Map; }; /** Session usage totals distributed across model turns. */ interface ISessionUsageTotals { /** Cumulative input tokens — only set when known from an exact source (`session.shutdown`). */ readonly inputTokens?: number; /** Cumulative cache-read tokens — only set when known from an exact source. */ readonly cacheReadTokens?: number; /** Cumulative Copilot AIU (nano). */ readonly totalNanoAiu: number; } /** Parses a line-delimited JSON stream, skipping blank or malformed lines. */ export declare function parseJsonl(text: string): IAgentHostEventRecord[]; export {};