Path: blob/main/src/vs/workbench/contrib/chat/browser/promptSyntax/promptFileRewriter.ts
5254 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { CancellationToken } from '../../../../../base/common/cancellation.js';6import { URI } from '../../../../../base/common/uri.js';7import { ICodeEditorService } from '../../../../../editor/browser/services/codeEditorService.js';8import { EditOperation } from '../../../../../editor/common/core/editOperation.js';9import { Range } from '../../../../../editor/common/core/range.js';10import { ITextModel } from '../../../../../editor/common/model.js';11import { ILanguageModelToolsService, IToolAndToolSetEnablementMap } from '../../common/tools/languageModelToolsService.js';12import { PromptHeaderAttributes } from '../../common/promptSyntax/promptFileParser.js';13import { IPromptsService } from '../../common/promptSyntax/service/promptsService.js';14import { formatArrayValue } from '../../common/promptSyntax/utils/promptEditHelper.js';1516export class PromptFileRewriter {17constructor(18@ICodeEditorService private readonly _codeEditorService: ICodeEditorService,19@IPromptsService private readonly _promptsService: IPromptsService,20@ILanguageModelToolsService private readonly _languageModelToolsService: ILanguageModelToolsService21) {22}2324public async openAndRewriteTools(uri: URI, newTools: IToolAndToolSetEnablementMap | undefined, token: CancellationToken): Promise<void> {25const editor = await this._codeEditorService.openCodeEditor({ resource: uri }, this._codeEditorService.getFocusedCodeEditor());26if (!editor || !editor.hasModel()) {27return;28}29const model = editor.getModel();3031const promptAST = this._promptsService.getParsedPromptFile(model);32if (!promptAST.header) {33return undefined;34}3536const toolsAttr = promptAST.header.getAttribute(PromptHeaderAttributes.tools);37if (!toolsAttr) {38return undefined;39}4041editor.setSelection(toolsAttr.range);42if (newTools === undefined) {43this.rewriteAttribute(model, '', toolsAttr.range);44return;45} else {46this.rewriteTools(model, newTools, toolsAttr.value.range, toolsAttr.value.type === 'string');47}48}4950public rewriteTools(model: ITextModel, newTools: IToolAndToolSetEnablementMap, range: Range, isString: boolean): void {51const newToolNames = this._languageModelToolsService.toFullReferenceNames(newTools);52const newEntries = newToolNames.map(toolName => formatArrayValue(toolName)).join(', ');53const newValue = isString ? newEntries : `[${newEntries}]`;54this.rewriteAttribute(model, newValue, range);55}5657private rewriteAttribute(model: ITextModel, newValue: string, range: Range): void {58model.pushStackElement();59model.pushEditOperations(null, [EditOperation.replaceMove(range, newValue)], () => null);60model.pushStackElement();61}6263public async openAndRewriteName(uri: URI, newName: string, token: CancellationToken): Promise<void> {64const editor = await this._codeEditorService.openCodeEditor({ resource: uri }, this._codeEditorService.getFocusedCodeEditor());65if (!editor || !editor.hasModel()) {66return;67}68const model = editor.getModel();6970const promptAST = this._promptsService.getParsedPromptFile(model);71if (!promptAST.header) {72return;73}7475const nameAttr = promptAST.header.getAttribute(PromptHeaderAttributes.name);76if (!nameAttr) {77return;78}79if (nameAttr.value.type === 'string' && nameAttr.value.value === newName) {80return;81}8283editor.setSelection(nameAttr.range);84this.rewriteAttribute(model, newName, nameAttr.value.range);85}86}87888990