Skip to content

Commit 30f15d8

Browse files
authored
Preserve chat references when delegating to CLI using new approach (#2315)
* Preserve chat references when delegating to CLI using new approach * Fixes
1 parent 0295ec3 commit 30f15d8

File tree

1 file changed

+34
-20
lines changed

1 file changed

+34
-20
lines changed

src/extension/chatSessions/vscode-node/copilotCLIChatSessionsContribution.ts

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { SweCustomAgent } from '@github/copilot/sdk';
6+
import { Attachment, SweCustomAgent } from '@github/copilot/sdk';
77
import * as l10n from '@vscode/l10n';
88
import * as vscode from 'vscode';
99
import { ChatExtendedRequestHandler, Uri } from 'vscode';
@@ -434,6 +434,7 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
434434
}
435435

436436
private readonly previousReferences = new Map<string, vscode.ChatPromptReference[]>();
437+
private readonly attachmentsForRequest = new Map<string, Attachment[]>();
437438
private async handleRequest(request: vscode.ChatRequest, context: vscode.ChatContext, stream: vscode.ChatResponseStream, token: vscode.CancellationToken): Promise<vscode.ChatResult | void> {
438439
const { chatSessionContext } = context;
439440
const disposables = new DisposableStore();
@@ -493,6 +494,11 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
493494

494495
if (request.prompt.startsWith('/delegate')) {
495496
await this.handleDelegateCommand(session.object, request, context, stream, token);
497+
} else if (this.attachmentsForRequest.has(session.object.sessionId)) {
498+
// This is a request that was created in createCLISessionAndSubmitRequest with attachments already resolved.
499+
const attachments = this.attachmentsForRequest.get(session.object.sessionId)!;
500+
this.attachmentsForRequest.delete(session.object.sessionId);
501+
await session.object.handleRequest(request.id, request.prompt, attachments, modelId, token);
496502
} else {
497503
// Construct the full prompt with references to be sent to CLI.
498504
const { prompt, attachments } = await this.promptResolver.resolvePrompt(request, undefined, additionalReferences, session.object.options.isolationEnabled, token);
@@ -811,31 +817,37 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
811817
token: vscode.CancellationToken
812818
): Promise<vscode.ChatResult> {
813819
let history: string | undefined;
820+
const requestPromptPromise = (async () => {
821+
if (this.hasHistoryToSummarize(context.history)) {
822+
stream.progress(vscode.l10n.t('Analyzing chat history'));
823+
history = await this.chatDelegationSummaryService.summarize(context, token);
824+
history = history ? `**Summary**\n${history}` : undefined;
825+
}
814826

815-
if (this.hasHistoryToSummarize(context.history)) {
816-
stream.progress(vscode.l10n.t('Analyzing chat history'));
817-
history = await this.chatDelegationSummaryService.summarize(context, token);
818-
history = history ? `**Summary**\n${history}` : undefined;
819-
}
827+
// Give priority to userPrompt if provided (e.g., from confirmation metadata)
828+
userPrompt = userPrompt || request.prompt;
829+
return history ? `${userPrompt}\n${history}` : userPrompt;
830+
})();
820831

821-
// Give priority to userPrompt if provided (e.g., from confirmation metadata)
822-
userPrompt = userPrompt || request.prompt;
823-
const requestPrompt = history ? `${userPrompt}\n${history}` : userPrompt;
832+
const getWorkingDirectory = async () => {
833+
// Create worktree if isolation is enabled and we don't have one yet
834+
if (isolationEnabled && !workingDirectory) {
835+
const workTreePath = await this.worktreeManager.createWorktree(stream);
836+
workingDirectory = workTreePath ? URI.file(workTreePath) : undefined;
837+
}
824838

825-
// Create worktree if isolation is enabled and we don't have one yet
826-
if (isolationEnabled && !workingDirectory) {
827-
const workTreePath = await this.worktreeManager.createWorktree(stream);
828-
workingDirectory = workTreePath ? URI.file(workTreePath) : undefined;
829-
}
839+
// Fallback to default directory if worktree creation failed
840+
if (!isolationEnabled && !workingDirectory) {
841+
workingDirectory = await this.copilotCLISDK.getDefaultWorkingDirectory();
842+
}
843+
};
830844

831-
// Fallback to default directory if worktree creation failed
832-
if (!workingDirectory && !isolationEnabled) {
833-
workingDirectory = await this.copilotCLISDK.getDefaultWorkingDirectory();
834-
}
835-
const [{ prompt, attachments }, model, agent] = await Promise.all([
836-
this.promptResolver.resolvePrompt(request, requestPrompt, (references || []).concat([]), isolationEnabled, token),
845+
const [requestPrompt, { prompt, attachments }, model, agent] = await Promise.all([
846+
requestPromptPromise,
847+
requestPromptPromise.then(prompt => this.promptResolver.resolvePrompt(request, prompt, (references || []).concat([]), isolationEnabled, token)),
837848
this.getModelId(undefined, undefined, token),
838849
this.getAgent(undefined, undefined, token),
850+
getWorkingDirectory()
839851
]);
840852

841853
const session = await this.sessionService.createSession({ workingDirectory, isolationEnabled, agent, model }, token);
@@ -849,12 +861,14 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
849861
}
850862

851863
try {
864+
this.attachmentsForRequest.set(session.object.sessionId, attachments);
852865
this.sessionItemProvider.notifySessionsChange();
853866
await vscode.commands.executeCommand('workbench.action.chat.openSessionWithPrompt.copilotcli', {
854867
resource: SessionIdForCLI.getResource(session.object.sessionId),
855868
prompt: requestPrompt
856869
});
857870
} catch {
871+
this.attachmentsForRequest.delete(session.object.sessionId);
858872
// TODO@rebornix: handle potential missing command
859873
// We don't want to block the caller anymore.
860874
// The caller is most likely a chat editor or the like.

0 commit comments

Comments
 (0)