Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/chat/browser/promptSyntax/promptFileRewriter.ts
3296 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 { CancellationToken } from '../../../../../base/common/cancellation.js';
7
import { URI } from '../../../../../base/common/uri.js';
8
import { ICodeEditorService } from '../../../../../editor/browser/services/codeEditorService.js';
9
import { EditOperation } from '../../../../../editor/common/core/editOperation.js';
10
import { Range } from '../../../../../editor/common/core/range.js';
11
import { ITextModel } from '../../../../../editor/common/model.js';
12
import { IToolAndToolSetEnablementMap, IToolData, ToolSet } from '../../common/languageModelToolsService.js';
13
import { IPromptsService } from '../../common/promptSyntax/service/promptsService.js';
14
15
export class PromptFileRewriter {
16
constructor(
17
@ICodeEditorService private readonly _codeEditorService: ICodeEditorService,
18
@IPromptsService private readonly _promptsService: IPromptsService
19
) {
20
}
21
22
public async openAndRewriteTools(uri: URI, newTools: IToolAndToolSetEnablementMap | undefined, token: CancellationToken): Promise<void> {
23
const editor = await this._codeEditorService.openCodeEditor({ resource: uri }, this._codeEditorService.getFocusedCodeEditor());
24
if (!editor || !editor.hasModel()) {
25
return;
26
}
27
const model = editor.getModel();
28
29
const parser = this._promptsService.getSyntaxParserFor(model);
30
await parser.start(token).settled();
31
const { header } = parser;
32
if (header === undefined) {
33
return undefined;
34
}
35
36
const completed = await header.settled;
37
if (!completed || token.isCancellationRequested) {
38
return;
39
}
40
41
if (('tools' in header.metadataUtility) === false) {
42
return undefined;
43
}
44
const { tools } = header.metadataUtility;
45
if (tools === undefined) {
46
return undefined;
47
}
48
editor.setSelection(tools.range);
49
this.rewriteTools(model, newTools, tools.range);
50
}
51
52
53
public rewriteTools(model: ITextModel, newTools: IToolAndToolSetEnablementMap | undefined, range: Range): void {
54
const newString = newTools === undefined ? '' : `tools: ${this.getNewValueString(newTools)}`;
55
model.pushStackElement();
56
model.pushEditOperations(null, [EditOperation.replaceMove(range, newString)], () => null);
57
model.pushStackElement();
58
}
59
60
public getNewValueString(tools: IToolAndToolSetEnablementMap): string {
61
const newToolNames: string[] = [];
62
const toolsCoveredBySets = new Set<IToolData>();
63
for (const [item, picked] of tools) {
64
if (picked && item instanceof ToolSet) {
65
for (const tool of item.getTools()) {
66
toolsCoveredBySets.add(tool);
67
}
68
}
69
}
70
for (const [item, picked] of tools) {
71
if (picked) {
72
if (item instanceof ToolSet) {
73
newToolNames.push(item.referenceName);
74
} else if (!toolsCoveredBySets.has(item)) {
75
newToolNames.push(item.toolReferenceName ?? item.displayName);
76
}
77
}
78
}
79
return `[${newToolNames.map(s => `'${s}'`).join(', ')}]`;
80
}
81
}
82
83
84
85