diff --git a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts index 369d340afe..7e2136b72e 100644 --- a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts +++ b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts @@ -66,10 +66,10 @@ declare module 'vscode' { export class ChatResponseConfirmationPart { title: string; - message: string; + message: string | MarkdownString; data: any; buttons?: string[]; - constructor(title: string, message: string, data: any, buttons?: string[]); + constructor(title: string, message: string | MarkdownString, data: any, buttons?: string[]); } export class ChatResponseCodeCitationPart { @@ -84,8 +84,72 @@ declare module 'vscode' { constructor(toolName: string); } - export type ExtendedChatResponsePart = ChatResponsePart | ChatResponseTextEditPart | ChatResponseNotebookEditPart | ChatResponseConfirmationPart | ChatResponseCodeCitationPart | ChatResponseReferencePart2 | ChatResponseMovePart | ChatResponseExtensionsPart | ChatPrepareToolInvocationPart; + export interface ChatTerminalToolInvocationData { + commandLine: { + original: string; + userEdited?: string; + toolEdited?: string; + }; + language: string; + } + + export class ChatToolInvocationPart { + toolName: string; + toolCallId: string; + isError?: boolean; + invocationMessage?: string | MarkdownString; + originMessage?: string | MarkdownString; + pastTenseMessage?: string | MarkdownString; + isConfirmed?: boolean; + isComplete?: boolean; + toolSpecificData?: ChatTerminalToolInvocationData; + + constructor(toolName: string, toolCallId: string, isError?: boolean); + } + + /** + * Represents a single file diff entry in a multi diff view. + */ + export interface ChatResponseDiffEntry { + /** + * The original file URI (undefined for new files). + */ + originalUri?: Uri; + + /** + * The modified file URI (undefined for deleted files). + */ + modifiedUri?: Uri; + + /** + * Optional URI to navigate to when clicking on the file. + */ + goToFileUri?: Uri; + } + /** + * Represents a part of a chat response that shows multiple file diffs. + */ + export class ChatResponseMultiDiffPart { + /** + * Array of file diff entries to display. + */ + value: ChatResponseDiffEntry[]; + + /** + * The title for the multi diff editor. + */ + title: string; + + /** + * Create a new ChatResponseMultiDiffPart. + * @param value Array of file diff entries. + * @param title The title for the multi diff editor. + */ + constructor(value: ChatResponseDiffEntry[], title: string); + } + + export type ExtendedChatResponsePart = ChatResponsePart | ChatResponseTextEditPart | ChatResponseNotebookEditPart | ChatResponseConfirmationPart | ChatResponseCodeCitationPart | ChatResponseReferencePart2 | ChatResponseMovePart | ChatResponseExtensionsPart | ChatResponsePullRequestPart | ChatPrepareToolInvocationPart | ChatToolInvocationPart | ChatResponseMultiDiffPart; export class ChatResponseWarningPart { value: MarkdownString; constructor(value: string | MarkdownString); @@ -171,6 +235,15 @@ declare module 'vscode' { constructor(extensions: string[]); } + export class ChatResponsePullRequestPart { + readonly uri: Uri; + readonly linkTag: string; + readonly title: string; + readonly description: string; + readonly author: string; + constructor(uri: Uri, title: string, description: string, author: string, linkTag: string); + } + export interface ChatResponseStream { /** @@ -205,7 +278,7 @@ declare module 'vscode' { * TODO@API should this be MarkdownString? * TODO@API should actually be a more generic function that takes an array of buttons */ - confirmation(title: string, message: string, data: any, buttons?: string[]): void; + confirmation(title: string, message: string | MarkdownString, data: any, buttons?: string[]): void; /** * Push a warning to this stream. Short-hand for @@ -258,6 +331,50 @@ declare module 'vscode' { readonly tools: Map; } + export namespace lm { + /** + * Fired when the set of tools on a chat request changes. + */ + export const onDidChangeChatRequestTools: Event; + } + + export class LanguageModelToolExtensionSource { + /** + * ID of the extension that published the tool. + */ + readonly id: string; + + /** + * Label of the extension that published the tool. + */ + readonly label: string; + + private constructor(id: string, label: string); + } + + export class LanguageModelToolMCPSource { + /** + * Editor-configured label of the MCP server that published the tool. + */ + readonly label: string; + + /** + * Server-defined name of the MCP server. + */ + readonly name: string; + + /** + * Server-defined instructions for MCP tool use. + */ + readonly instructions?: string; + + private constructor(label: string, name: string, instructions?: string); + } + + export interface LanguageModelToolInformation { + source: LanguageModelToolExtensionSource | LanguageModelToolMCPSource | undefined; + } + // TODO@API fit this into the stream export interface ChatUsedContext { documents: ChatDocumentContext[]; @@ -307,6 +424,10 @@ declare module 'vscode' { participant?: string; command?: string; }; + /** + * An optional detail string that will be rendered at the end of the response in certain UI contexts. + */ + details?: string; } export namespace chat { @@ -401,6 +522,15 @@ declare module 'vscode' { outcome: ChatEditingSessionActionOutcome; } + export interface ChatEditingHunkAction { + // eslint-disable-next-line local/vscode-dts-string-type-literals + kind: 'chatEditingHunkAction'; + uri: Uri; + lineCount: number; + outcome: ChatEditingSessionActionOutcome; + hasRemainingEdits: boolean; + } + export enum ChatEditingSessionActionOutcome { Accepted = 1, Rejected = 2, @@ -409,7 +539,7 @@ declare module 'vscode' { export interface ChatUserActionEvent { readonly result: ChatResult; - readonly action: ChatCopyAction | ChatInsertAction | ChatApplyAction | ChatTerminalAction | ChatCommandAction | ChatFollowupAction | ChatBugReportAction | ChatEditorAction | ChatEditingSessionAction; + readonly action: ChatCopyAction | ChatInsertAction | ChatApplyAction | ChatTerminalAction | ChatCommandAction | ChatFollowupAction | ChatBugReportAction | ChatEditorAction | ChatEditingSessionAction | ChatEditingHunkAction; } export interface ChatPromptReference { diff --git a/src/@types/vscode.proposed.chatParticipantPrivate.d.ts b/src/@types/vscode.proposed.chatParticipantPrivate.d.ts index 470a2ca4ce..907bb0a80c 100644 --- a/src/@types/vscode.proposed.chatParticipantPrivate.d.ts +++ b/src/@types/vscode.proposed.chatParticipantPrivate.d.ts @@ -137,7 +137,31 @@ declare module 'vscode' { /** * @hidden */ - private constructor(prompt: string, command: string | undefined, references: ChatPromptReference[], participant: string, toolReferences: ChatLanguageModelToolReference[], editedFileEvents: ChatRequestEditedFileEvent[] | undefined); + constructor(prompt: string, command: string | undefined, references: ChatPromptReference[], participant: string, toolReferences: ChatLanguageModelToolReference[], editedFileEvents: ChatRequestEditedFileEvent[] | undefined); + } + + export class ChatResponseTurn2 { + /** + * The content that was received from the chat participant. Only the stream parts that represent actual content (not metadata) are represented. + */ + readonly response: ReadonlyArray; + + /** + * The result that was received from the chat participant. + */ + readonly result: ChatResult; + + /** + * The id of the chat participant that this response came from. + */ + readonly participant: string; + + /** + * The name of the command that this response came from. + */ + readonly command?: string; + + constructor(response: ReadonlyArray, result: ChatResult, participant: string); } export interface ChatParticipant { @@ -205,24 +229,6 @@ declare module 'vscode' { presentation?: 'hidden' | undefined; } - export interface LanguageModelTool { - prepareInvocation2?(options: LanguageModelToolInvocationPrepareOptions, token: CancellationToken): ProviderResult; - } - - export class PreparedTerminalToolInvocation { - readonly command: string; - readonly language: string; - readonly confirmationMessages?: LanguageModelToolConfirmationMessages; - readonly presentation?: 'hidden' | undefined; - - constructor( - command: string, - language: string, - confirmationMessages?: LanguageModelToolConfirmationMessages, - presentation?: 'hidden' - ); - } - export class ExtendedLanguageModelToolResult extends LanguageModelToolResult { toolResultMessage?: string | MarkdownString; toolResultDetails?: Array; diff --git a/src/github/copilotRemoteAgent.ts b/src/github/copilotRemoteAgent.ts index 06dd96b4e5..4461e63f9d 100644 --- a/src/github/copilotRemoteAgent.ts +++ b/src/github/copilotRemoteAgent.ts @@ -280,6 +280,15 @@ export class CopilotRemoteAgentManager extends Disposable { // Group 2 is this, url-encoded: // {"owner":"monalisa","repo":"app","pullRequestNumber":18} let followUpPR: number | undefined = this.parseFollowup(followup, repoInfo); + + // Check if the currently active PR is a coding agent PR + if (!followUpPR) { + const activePR = repoInfo.fm.activePullRequest; + if (activePR && this._stateModel.get(owner, repo, activePR.number)) { + followUpPR = activePR.number; + } + } + if (followUpPR) { return this.addFollowUpToExistingPR(followUpPR, userPrompt, summary); } diff --git a/src/github/utils.ts b/src/github/utils.ts index e4594c6d63..5ce7b79105 100644 --- a/src/github/utils.ts +++ b/src/github/utils.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import * as OctokitTypes from '@octokit/types'; import * as crypto from 'crypto'; +import * as OctokitTypes from '@octokit/types'; import * as vscode from 'vscode'; import { Repository } from '../api/api'; import { GitApiImpl } from '../api/api1';