5
5
6
6
import { CancellationToken } from '../../../../../base/common/cancellation.js' ;
7
7
import { MarkdownString } from '../../../../../base/common/htmlContent.js' ;
8
- import { Disposable , IDisposable } from '../../../../../base/common/lifecycle.js' ;
8
+ import { IDisposable } from '../../../../../base/common/lifecycle.js' ;
9
9
import { autorun } from '../../../../../base/common/observable.js' ;
10
- import { URI } from '../../../../../base/common/uri.js' ;
10
+ import { URI , UriComponents } from '../../../../../base/common/uri.js' ;
11
11
import { localize } from '../../../../../nls.js' ;
12
- import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js' ;
13
12
import { IWorkspaceContextService } from '../../../../../platform/workspace/common/workspace.js' ;
14
- import { IWorkbenchContribution } from '../../../../common/contributions.js' ;
15
13
import { SaveReason } from '../../../../common/editor.js' ;
16
14
import { ITextFileService } from '../../../../services/textfile/common/textfiles.js' ;
17
15
import { ICodeMapperService } from '../../common/chatCodeMapperService.js' ;
18
16
import { IChatEditingService } from '../../common/chatEditingService.js' ;
19
17
import { ChatModel } from '../../common/chatModel.js' ;
20
18
import { IChatService } from '../../common/chatService.js' ;
21
19
import { ILanguageModelIgnoredFilesService } from '../../common/ignoredFiles.js' ;
22
- import { CountTokensCallback , ILanguageModelToolsService , IToolData , IToolImpl , IToolInvocation , IToolResult } from '../../common/languageModelToolsService.js' ;
23
-
24
- export class BuiltinToolsContribution extends Disposable implements IWorkbenchContribution {
25
-
26
- static readonly ID = 'chat.builtinTools' ;
27
-
28
- constructor (
29
- @ILanguageModelToolsService toolsService : ILanguageModelToolsService ,
30
- @IInstantiationService instantiationService : IInstantiationService ,
31
- ) {
32
- super ( ) ;
33
-
34
- const editTool = instantiationService . createInstance ( EditTool ) ;
35
- this . _register ( toolsService . registerToolData ( editToolData ) ) ;
36
- this . _register ( toolsService . registerToolImplementation ( editToolData . id , editTool ) ) ;
37
- }
38
- }
39
-
40
- interface EditToolParams {
41
- filePath : string ;
42
- explanation : string ;
43
- code : string ;
44
- }
20
+ import { CountTokensCallback , IToolData , IToolImpl , IToolInvocation , IToolResult } from '../../common/languageModelToolsService.js' ;
21
+ import { IToolInputProcessor } from './tools.js' ;
45
22
46
23
const codeInstructions = `
47
24
The user is very smart and can understand how to apply your edits to their files, you just need to provide minimal hints.
@@ -63,7 +40,7 @@ class Person {
63
40
}
64
41
` ;
65
42
66
- const editToolData : IToolData = {
43
+ export const EditToolData : IToolData = {
67
44
id : 'vscode_editFile' ,
68
45
tags : [ 'vscode_editing' ] ,
69
46
displayName : localize ( 'chat.tools.editFile' , "Edit File" ) ,
@@ -88,7 +65,7 @@ const editToolData: IToolData = {
88
65
}
89
66
} ;
90
67
91
- class EditTool implements IToolImpl {
68
+ export class EditTool implements IToolImpl {
92
69
93
70
constructor (
94
71
@IChatService private readonly chatService : IChatService ,
@@ -105,13 +82,13 @@ class EditTool implements IToolImpl {
105
82
}
106
83
107
84
const parameters = invocation . parameters as EditToolParams ;
108
- const uri = URI . file ( parameters . filePath ) ;
85
+ const uri = URI . revive ( parameters . file ) ; // TODO @roblourens do revive in MainThreadLanguageModelTools
109
86
if ( ! this . workspaceContextService . isInsideWorkspace ( uri ) ) {
110
- throw new Error ( `File ${ parameters . filePath } can't be edited because it's not inside the current workspace` ) ;
87
+ throw new Error ( `File ${ uri . fsPath } can't be edited because it's not inside the current workspace` ) ;
111
88
}
112
89
113
90
if ( await this . ignoredFilesService . fileIsIgnored ( uri , token ) ) {
114
- throw new Error ( `File ${ parameters . filePath } can't be edited because it is configured to be ignored by Copilot` ) ;
91
+ throw new Error ( `File ${ uri . fsPath } can't be edited because it is configured to be ignored by Copilot` ) ;
115
92
}
116
93
117
94
const model = this . chatService . getSession ( invocation . context ?. sessionId ) as ChatModel ;
@@ -182,3 +159,31 @@ class EditTool implements IToolImpl {
182
159
} ;
183
160
}
184
161
}
162
+
163
+ export interface EditToolParams {
164
+ file : UriComponents ;
165
+ explanation : string ;
166
+ code : string ;
167
+ }
168
+
169
+ export interface EditToolRawParams {
170
+ filePath : string ;
171
+ explanation : string ;
172
+ code : string ;
173
+ }
174
+
175
+ export class EditToolInputProcessor implements IToolInputProcessor {
176
+ processInput ( input : EditToolRawParams ) : EditToolParams {
177
+ if ( ! input . filePath ) {
178
+ // Tool name collision, or input wasn't properly validated upstream
179
+ return input as any ;
180
+ }
181
+
182
+ // Runs in EH, will be mapped
183
+ return {
184
+ file : URI . file ( input . filePath ) ,
185
+ explanation : input . explanation ,
186
+ code : input . code ,
187
+ } ;
188
+ }
189
+ }
0 commit comments