diff --git a/src/extension/prompt/vscode-node/requestLoggerImpl.ts b/src/extension/prompt/vscode-node/requestLoggerImpl.ts index 744f910d60..c47556ed22 100644 --- a/src/extension/prompt/vscode-node/requestLoggerImpl.ts +++ b/src/extension/prompt/vscode-node/requestLoggerImpl.ts @@ -5,7 +5,7 @@ import { RequestMetadata, RequestType } from '@vscode/copilot-api'; import { HTMLTracer, IChatEndpointInfo, RenderPromptResult } from '@vscode/prompt-tsx'; -import { CancellationToken, DocumentLink, DocumentLinkProvider, ExtendedLanguageModelToolResult, LanguageModelDataPart, LanguageModelPromptTsxPart, LanguageModelTextPart, LanguageModelToolResult2, languages, Range, TextDocument, Uri, workspace } from 'vscode'; +import { CancellationToken, DocumentLink, DocumentLinkProvider, ExtendedLanguageModelToolResult, LanguageModelDataPart, LanguageModelPromptTsxPart, LanguageModelTextPart, LanguageModelToolResult2, languages, MarkdownString, Range, TextDocument, Uri, workspace } from 'vscode'; import { ChatFetchResponseType } from '../../../platform/chat/common/commonTypes'; import { ConfigKey, IConfigurationService, XTabProviderId } from '../../../platform/configuration/common/configurationService'; import { IModelAPIResponse } from '../../../platform/endpoint/common/endpointProvider'; @@ -201,6 +201,9 @@ class LoggedToolCall implements ILoggedToolCall { public readonly thinking?: ThinkingData, public readonly edits?: { path: string; edits: string }[], public readonly toolMetadata?: unknown, + public readonly toolResultMessage?: string, + public readonly toolResultError?: string, + public readonly hasError?: boolean, ) { } async toJSON(): Promise { @@ -229,7 +232,10 @@ class LoggedToolCall implements ILoggedToolCall { response: responseData, thinking: thinking, edits: this.edits ? this.edits.map(edit => ({ path: edit.path, edits: JSON.parse(edit.edits) })) : undefined, - toolMetadata: this.toolMetadata + toolMetadata: this.toolMetadata, + toolResultMessage: this.toolResultMessage, + toolResultError: this.toolResultError, + hasError: this.hasError }; } } @@ -299,8 +305,13 @@ export class RequestLogger extends AbstractRequestLogger { public override logToolCall(id: string, name: string, args: unknown, response: LanguageModelToolResult2, thinking?: ThinkingData): void { const edits = this._workspaceEditRecorder?.getEditsAndReset(); - // Extract toolMetadata from response if it exists const toolMetadata = 'toolMetadata' in response ? (response as ExtendedLanguageModelToolResult).toolMetadata : undefined; + let toolResultMessage = 'toolResultMessage' in response ? (response as ExtendedLanguageModelToolResult).toolResultMessage : undefined; + if (toolResultMessage instanceof MarkdownString) { + toolResultMessage = toolResultMessage.value; + } + const toolResultError = 'toolResultError' in response ? (response as ExtendedLanguageModelToolResult).toolResultError : undefined; + const hasError = 'hasError' in response ? (response as ExtendedLanguageModelToolResult).hasError : undefined; this._addEntry(new LoggedToolCall( id, name, @@ -310,7 +321,10 @@ export class RequestLogger extends AbstractRequestLogger { Date.now(), thinking, edits, - toolMetadata + toolMetadata, + toolResultMessage, + toolResultError, + hasError )); } @@ -474,6 +488,7 @@ export class RequestLogger extends AbstractRequestLogger { result.push(`id : ${entry.id}`); result.push(`tool : ${entry.name}`); result.push(`args : ${args}`); + result.push(`metadata : ${JSON.stringify(entry.toolMetadata, undefined, 2)}`); result.push(`~~~`); result.push(`## Response`); @@ -500,6 +515,27 @@ export class RequestLogger extends AbstractRequestLogger { result.push(`~~~`); } + if (entry.toolResultMessage) { + result.push(`## Tool Result Message`); + result.push(`~~~`); + result.push(entry.toolResultMessage); + result.push(`~~~`); + } + + if (entry.toolResultError) { + result.push(`## Tool Result Error`); + result.push(`~~~`); + result.push(entry.toolResultError); + result.push(`~~~`); + } + + if (entry.hasError !== undefined) { + result.push(`## Has Error`); + result.push(`~~~`); + result.push(entry.hasError.toString()); + result.push(`~~~`); + } + return result.join('\n'); } diff --git a/src/extension/vscode.proposed.chatParticipantPrivate.d.ts b/src/extension/vscode.proposed.chatParticipantPrivate.d.ts index 59dd414ad6..2c900988b4 100644 --- a/src/extension/vscode.proposed.chatParticipantPrivate.d.ts +++ b/src/extension/vscode.proposed.chatParticipantPrivate.d.ts @@ -251,6 +251,7 @@ declare module 'vscode' { export class ExtendedLanguageModelToolResult extends LanguageModelToolResult { toolResultMessage?: string | MarkdownString; toolResultDetails?: Array; + toolResultError?: string; toolMetadata?: unknown; /** Whether there was an error calling the tool. The tool may still have partially succeeded. */ hasError?: boolean; diff --git a/src/platform/requestLogger/node/requestLogger.ts b/src/platform/requestLogger/node/requestLogger.ts index 54b1e05b18..2169090946 100644 --- a/src/platform/requestLogger/node/requestLogger.ts +++ b/src/platform/requestLogger/node/requestLogger.ts @@ -124,6 +124,10 @@ export interface ILoggedToolCall { token: CapturingToken | undefined; time: number; thinking?: ThinkingData; + toolMetadata?: unknown; + toolResultMessage?: string; + toolResultError?: string; + hasError?: boolean; toJSON(): Promise; }