Path: blob/main/extensions/copilot/src/extension/log/node/chatLogExport.ts
13399 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 { LoggedInfo, LoggedInfoKind } from '../../../platform/requestLogger/common/requestLogger';67/**8* Type for a log entry in an exported chat log file.9* These types correspond to LoggedInfoKind from the request logger.10*/11type ExportedLogKind = 'element' | 'request' | 'toolCall' | 'error';1213/**14* Metadata attached to request entries.15*/16interface ExportedLogMetadata {17model?: string;18duration?: number;19startTime?: string;20endTime?: string;21usage?: {22prompt_tokens?: number;23completion_tokens?: number;24total_tokens?: number;25};26}2728/**29* Exported log entry from a chat log export file.30* This is the serialized form of LoggedInfo.31*/32interface ExportedLogEntry {33id: string;34kind: ExportedLogKind;35/** Name of the element or request */36name?: string;37/** Tool name for tool call entries */38tool?: string;39/** Request type (e.g., 'ChatMLSuccess', 'ChatMLFailure', 'MarkdownContentRequest') */40type?: string;41/** Token count for element entries */42tokens?: number;43/** Max tokens for element entries */44maxTokens?: number;45/** Arguments for tool call entries */46args?: Record<string, unknown>;47/** Response from tool or model */48response?: object;49/** Markdown content for MarkdownContentRequest entries - displayed directly to user */50content?: string;51/** Metadata for request entries */52metadata?: ExportedLogMetadata;53/** Raw request messages */54requestMessages?: {55messages?: unknown[];56};57/** Timestamp */58time?: string;59/** Thinking content for reasoning models */60thinking?: {61id?: string;62text?: string;63};64/** Error message for error entries */65error?: string;66/** Timestamp for when the entry occurred */67timestamp?: string;68}6970/**71* Structure of an exported prompt in a chat log export file.72* Each prompt represents a user query and its associated log entries.73*/74export interface ExportedPrompt {75/** The user's prompt text */76prompt: string;77/** Unique identifier for the prompt */78promptId?: string;79/** Whether this is a continuation of a previous conversation */80hasSeen?: boolean;81/** Number of log entries in this prompt */82logCount: number;83/** The log entries for this prompt */84logs: ExportedLogEntry[];85}8687/**88* Root structure of a chat log export file.89*/90export interface ChatLogExport {91/** ISO timestamp of when the export was created */92exportedAt: string;93/** Total number of prompts in the export */94totalPrompts: number;95/** Total number of log entries across all prompts */96totalLogEntries: number;97/** Array of exported prompts */98prompts: ExportedPrompt[];99/** MCP server definitions active during the session */100mcpServers?: object[];101}102103/**104* Converts a single log entry to its JSON representation.105* Handles async toJSON methods for tool calls.106*/107async function entryToJson(entry: LoggedInfo): Promise<object> {108if (entry.kind === LoggedInfoKind.ToolCall) {109// Tool calls have async toJSON110return await (entry as { toJSON(): Promise<object> }).toJSON();111} else {112// Elements and requests have sync toJSON113return (entry as { toJSON(): object }).toJSON();114}115}116117/**118* Creates an exported prompt from a collection of log entries.119* Use this when entries are already grouped by prompt (e.g., from tree view).120*121* @param label - The prompt label122* @param entries - The log entries for this prompt123* @param options - Additional options124* @returns The exported prompt structure125*/126export async function createExportedPrompt(127label: string,128entries: LoggedInfo[],129options?: { promptId?: string; hasSeen?: boolean }130): Promise<ExportedPrompt> {131const logs: ExportedLogEntry[] = [];132for (const entry of entries) {133try {134logs.push(await entryToJson(entry) as ExportedLogEntry);135} catch (error) {136logs.push({137id: entry.id,138kind: 'error',139error: error?.toString() || 'Unknown error',140timestamp: new Date().toISOString()141});142}143}144145return {146prompt: label,147promptId: options?.promptId,148hasSeen: options?.hasSeen,149logCount: logs.length,150logs151};152}153154/**155* Assembles a complete ChatLogExport from exported prompts.156*157* @param prompts - Array of exported prompts158* @param mcpServers - Optional MCP server definitions159* @returns The complete export structure160*/161export function assembleChatLogExport(162prompts: ExportedPrompt[],163mcpServers?: object[]164): ChatLogExport {165const totalLogEntries = prompts.reduce((sum, p) => sum + p.logCount, 0);166167return {168exportedAt: new Date().toISOString(),169totalPrompts: prompts.length,170totalLogEntries,171prompts,172mcpServers173};174}175176/**177* Serializes a chat log export to a JSON string.178*/179export function serializeChatLogExport(exportData: ChatLogExport): string {180return JSON.stringify(exportData, null, 2);181}182183184