Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/extension/intents/node/generateNewWorkspaceContent.ts
13399 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import type { CancellationToken } from 'vscode';
7
import { ChatFetchResponseType, ChatLocation } from '../../../platform/chat/common/commonTypes';
8
import { IEndpointProvider } from '../../../platform/endpoint/common/endpointProvider';
9
import { IInstantiationService } from '../../../util/vs/platform/instantiation/common/instantiation';
10
import { PromptRenderer } from '../../prompts/node/base/promptRenderer';
11
import { FileContentsPrompt, NewWorkspaceContentsPromptProps, ProjectSpecificationPrompt } from '../../prompts/node/panel/newWorkspace/newWorkspaceContents';
12
13
14
abstract class NewWorkspaceContentGenerator {
15
16
constructor(
17
private readonly promptType: typeof FileContentsPrompt | typeof ProjectSpecificationPrompt,
18
@IEndpointProvider private readonly endpointProvider: IEndpointProvider,
19
@IInstantiationService private readonly instantiationService: IInstantiationService,
20
) { }
21
22
public async generate(promptArgs: NewWorkspaceContentsPromptProps, token: CancellationToken): Promise<string> {
23
const endpoint = await this.endpointProvider.getChatEndpoint('copilot-fast');
24
const promptRenderer = PromptRenderer.create(this.instantiationService, endpoint, this.promptType, promptArgs);
25
const prompt = await promptRenderer.render();
26
27
const fetchResult = await endpoint
28
.makeChatRequest(
29
'newWorkspaceContentGenerator',
30
prompt.messages,
31
undefined,
32
token,
33
ChatLocation.Other,
34
undefined,
35
undefined,
36
);
37
38
return fetchResult.type === ChatFetchResponseType.Success ?
39
(promptArgs.filePath ? this.parseContents(promptArgs.filePath, fetchResult.value) : fetchResult.value) :
40
'';
41
}
42
43
protected abstract parseContents(filePath: string, chatResponse: string): string;
44
}
45
46
export class ProjectSpecificationGenerator extends NewWorkspaceContentGenerator {
47
constructor(
48
@IEndpointProvider endpointProvider: IEndpointProvider,
49
@IInstantiationService instantiationService: IInstantiationService
50
) {
51
super(ProjectSpecificationPrompt, endpointProvider, instantiationService);
52
}
53
54
protected override parseContents(chatResponse: string, filePath?: string | undefined): string {
55
throw new Error('Method not implemented.');
56
}
57
}
58
59
export class FileContentsGenerator extends NewWorkspaceContentGenerator {
60
constructor(
61
@IEndpointProvider endpointProvider: IEndpointProvider,
62
@IInstantiationService instantiationService: IInstantiationService,
63
) {
64
super(FileContentsPrompt, endpointProvider, instantiationService);
65
}
66
67
protected parseContents(filePath: string, chatResponse: string,): string {
68
function safeParse(str: string, regex: RegExp) {
69
try {
70
const match = regex.exec(str.trim());
71
if (match && match.length > 2) {
72
return match[2];
73
}
74
} catch (ex) {
75
console.error(ex);
76
}
77
78
return str;
79
}
80
81
if (filePath.endsWith('.md')) {
82
// If returned as a markdown codeblock, strip the codeblock markers
83
const fromCodeblock = safeParse(chatResponse, /^```([a-zA-Z]+)?\s*([\s\S]+?)\s*```$/);
84
// If returned as bare text, remove any text before the first header
85
const [preamble, ...withoutPreamble] = fromCodeblock.split('#');
86
if (preamble.length) {
87
return ['', ...withoutPreamble].join('#');
88
}
89
return fromCodeblock;
90
} else {
91
return safeParse(chatResponse, /```([^\n]+)?\s*\n([\s\S]+?)\s*```/g);
92
}
93
}
94
}
95
96