Skip to content

Commit 5d18692

Browse files
authored
Update prompt services to open text document instead of reading files (#2265)
1 parent bfcb502 commit 5d18692

File tree

5 files changed

+23
-30
lines changed

5 files changed

+23
-30
lines changed

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

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ import { IVSCodeExtensionContext } from '../../../platform/extContext/common/ext
1313
import { IGitService } from '../../../platform/git/common/gitService';
1414
import { toGitUri } from '../../../platform/git/common/utils';
1515
import { ILogService } from '../../../platform/log/common/logService';
16-
import { ParsedPromptFile, PromptFileParser } from '../../../platform/promptFiles/common/promptsService';
16+
import { IPromptsService, ParsedPromptFile } from '../../../platform/promptFiles/common/promptsService';
1717
import { ITelemetryService } from '../../../platform/telemetry/common/telemetry';
18-
import { IWorkspaceService } from '../../../platform/workspace/common/workspaceService';
1918
import { disposableTimeout } from '../../../util/vs/base/common/async';
2019
import { isCancellationError } from '../../../util/vs/base/common/errors';
2120
import { Emitter, Event } from '../../../util/vs/base/common/event';
@@ -414,7 +413,7 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
414413
@IConfigurationService private readonly configurationService: IConfigurationService,
415414
@ICopilotCLISDK private readonly copilotCLISDK: ICopilotCLISDK,
416415
@ILogService private readonly logService: ILogService,
417-
@IWorkspaceService private readonly workspaceService: IWorkspaceService,
416+
@IPromptsService private readonly promptsService: IPromptsService,
418417
) {
419418
super();
420419
}
@@ -458,8 +457,8 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
458457
const additionalReferences = this.previousReferences.get(id) || [];
459458
this.previousReferences.delete(id);
460459
const [modelId, agent] = await Promise.all([
461-
this.getModelId(id, request),
462-
this.getAgent(id, request),
460+
this.getModelId(id, request, token),
461+
this.getAgent(id, request, token),
463462
]);
464463
const session = await this.getOrCreateSession(request, chatSessionContext, modelId, agent, stream, disposables, token);
465464
if (!session || token.isCancellationRequested) {
@@ -511,8 +510,8 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
511510
* If opening an existing session, then uses the agent associated with that session.
512511
* If creating a new session with a prompt file that specifies an agent, then uses that agent.
513512
*/
514-
private async getAgent(sessionId: string | undefined, request: vscode.ChatRequest | undefined): Promise<SweCustomAgent | undefined> {
515-
const promptFile = request ? await this.getPromptInfoFromRequest(request) : undefined;
513+
private async getAgent(sessionId: string | undefined, request: vscode.ChatRequest | undefined, token: vscode.CancellationToken): Promise<SweCustomAgent | undefined> {
514+
const promptFile = request ? await this.getPromptInfoFromRequest(request, token) : undefined;
516515
if (promptFile?.header?.agent) {
517516
const agent = await this.copilotCLIAgents.resolveAgent(promptFile.header.agent);
518517
if (agent) {
@@ -527,14 +526,13 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
527526
return this.copilotCLIAgents.resolveAgent(sessionAgent ?? defaultAgent);
528527
}
529528

530-
private async getPromptInfoFromRequest(request: vscode.ChatRequest): Promise<ParsedPromptFile | undefined> {
529+
private async getPromptInfoFromRequest(request: vscode.ChatRequest, token: vscode.CancellationToken): Promise<ParsedPromptFile | undefined> {
531530
const promptFile = new ChatVariablesCollection(request.references).find(isPromptFile);
532531
if (!promptFile || !URI.isUri(promptFile.reference.value)) {
533532
return undefined;
534533
}
535534
try {
536-
const doc = await this.workspaceService.openTextDocument(promptFile.reference.value);
537-
return new PromptFileParser().parse(promptFile.reference.value, doc.getText());
535+
return await this.promptsService.parseFile(promptFile.reference.value, token);
538536
} catch (ex) {
539537
this.logService.error(`Failed to parse the prompt file: ${promptFile.reference.value.toString()}`, ex);
540538
return undefined;
@@ -571,8 +569,8 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
571569
return session;
572570
}
573571

574-
private async getModelId(sessionId: string | undefined, request: vscode.ChatRequest | undefined): Promise<string | undefined> {
575-
const promptFile = request ? await this.getPromptInfoFromRequest(request) : undefined;
572+
private async getModelId(sessionId: string | undefined, request: vscode.ChatRequest | undefined, token: vscode.CancellationToken): Promise<string | undefined> {
573+
const promptFile = request ? await this.getPromptInfoFromRequest(request, token) : undefined;
576574
if (promptFile?.header?.model) {
577575
const model = await this.copilotCLIModels.resolveModel(promptFile.header.model);
578576
if (model) {
@@ -812,8 +810,8 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
812810
}
813811
const [{ prompt, attachments }, model, agent] = await Promise.all([
814812
this.promptResolver.resolvePrompt(request, requestPrompt, (references || []).concat([]), isolationEnabled, token),
815-
this.getModelId(undefined, undefined),
816-
this.getAgent(undefined, undefined),
813+
this.getModelId(undefined, undefined, token),
814+
this.getAgent(undefined, undefined, token),
817815
]);
818816

819817
const session = await this.sessionService.createSession({ workingDirectory, isolationEnabled, agent, model }, token);

src/extension/chatSessions/vscode-node/test/copilotCLIChatSessionParticipant.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { IVSCodeExtensionContext } from '../../../../platform/extContext/common/
1515
import { MockFileSystemService } from '../../../../platform/filesystem/node/test/mockFileSystemService';
1616
import { IGitService } from '../../../../platform/git/common/gitService';
1717
import { ILogService } from '../../../../platform/log/common/logService';
18+
import { PromptsServiceImpl } from '../../../../platform/promptFiles/common/promptsServiceImpl';
1819
import { NullTelemetryService } from '../../../../platform/telemetry/common/nullTelemetryService';
1920
import type { ITelemetryService } from '../../../../platform/telemetry/common/telemetry';
2021
import { IWorkspaceService, NullWorkspaceService } from '../../../../platform/workspace/common/workspaceService';
@@ -190,7 +191,7 @@ describe('CopilotCLIChatSessionParticipant.handleRequest', () => {
190191
configurationService,
191192
copilotSDK,
192193
logger,
193-
new NullWorkspaceService()
194+
new PromptsServiceImpl(new NullWorkspaceService())
194195
);
195196
});
196197

src/extension/prompts/node/panel/promptFile.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
import { BasePromptElementProps, PromptElement, PromptReference, PromptSizing } from '@vscode/prompt-tsx';
77
import type { ChatLanguageModelToolReference } from 'vscode';
8-
import { IFileSystemService } from '../../../../platform/filesystem/common/fileSystemService';
98
import { IIgnoreService } from '../../../../platform/ignore/common/ignoreService';
109
import { ILogService } from '../../../../platform/log/common/logService';
1110
import { IPromptPathRepresentationService } from '../../../../platform/prompts/common/promptPathRepresentationService';
@@ -16,7 +15,6 @@ import { IPromptVariablesService } from '../../../prompt/node/promptVariablesSer
1615
import { EmbeddedInsideUserMessage } from '../base/promptElement';
1716
import { Tag } from '../base/tag';
1817
import { FilePathMode } from './fileVariable';
19-
import { isEqual } from '../../../../util/vs/base/common/resources';
2018

2119
export interface PromptFileProps extends BasePromptElementProps, EmbeddedInsideUserMessage {
2220
readonly variable: PromptVariable;
@@ -28,7 +26,6 @@ export class PromptFile extends PromptElement<PromptFileProps, void> {
2826

2927
constructor(
3028
props: PromptFileProps,
31-
@IFileSystemService private readonly fileSystemService: IFileSystemService,
3229
@IPromptVariablesService private readonly promptVariablesService: IPromptVariablesService,
3330
@ILogService private readonly logService: ILogService,
3431
@IPromptPathRepresentationService private readonly promptPathRepresentationService: IPromptPathRepresentationService,
@@ -65,8 +62,8 @@ export class PromptFile extends PromptElement<PromptFileProps, void> {
6562

6663
private async getBodyContent(fileUri: URI, toolReferences: readonly ChatLanguageModelToolReference[] | undefined): Promise<string | undefined> {
6764
try {
68-
const documentText = this.workspaceService.textDocuments.find(doc => isEqual(doc.uri, fileUri))?.getText();
69-
let content = documentText ?? new TextDecoder().decode(await this.fileSystemService.readFile(fileUri));
65+
const doc = await this.workspaceService.openTextDocument(fileUri);
66+
let content = doc.getText();
7067
if (toolReferences && toolReferences.length > 0) {
7168
content = await this.promptVariablesService.resolveToolReferencesInPrompt(content, toolReferences);
7269
}

src/platform/promptFiles/common/promptsService.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export namespace PromptFileLangageId {
2222
* A service that provides prompt file related functionalities: agents, instructions and prompt files.
2323
*/
2424
export interface IPromptsService {
25+
readonly _serviceBrand: undefined;
2526
/**
2627
* Reads and parses the provided URI
2728
* @param uris

src/platform/promptFiles/common/promptsServiceImpl.ts

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

6+
import { raceCancellationError } from '../../../util/vs/base/common/async';
67
import { CancellationToken } from '../../../util/vs/base/common/cancellation';
7-
import { CancellationError } from '../../../util/vs/base/common/errors';
88
import { URI } from '../../../util/vs/base/common/uri';
99
import { PromptFileParser } from '../../../util/vs/workbench/contrib/chat/common/promptSyntax/promptFileParser';
10-
import { IFileSystemService } from '../../filesystem/common/fileSystemService';
10+
import { IWorkspaceService } from '../../workspace/common/workspaceService';
1111
import { IPromptsService, ParsedPromptFile } from './promptsService';
1212

1313
export class PromptsServiceImpl implements IPromptsService {
14-
14+
declare _serviceBrand: undefined;
1515
constructor(
16-
@IFileSystemService private readonly fileService: IFileSystemService
16+
@IWorkspaceService private readonly workspaceService: IWorkspaceService
1717
) { }
1818

1919
public async parseFile(uri: URI, token: CancellationToken): Promise<ParsedPromptFile> {
20-
const fileContent = await this.fileService.readFile(uri);
21-
if (token.isCancellationRequested) {
22-
throw new CancellationError();
23-
}
24-
const text = new TextDecoder().decode(fileContent);
25-
return new PromptFileParser().parse(uri, text);
20+
const doc = await raceCancellationError(this.workspaceService.openTextDocument(uri), token);
21+
return new PromptFileParser().parse(uri, doc.getText());
2622
}
2723
}

0 commit comments

Comments
 (0)