6
6
import { CancellationToken } from '../../../../base/common/cancellation.js' ;
7
7
import { Disposable } from '../../../../base/common/lifecycle.js' ;
8
8
import { derived , IObservable , observableFromEvent , ObservableMap } from '../../../../base/common/observable.js' ;
9
- import { isObject } from '../../../../base/common/types.js' ;
10
9
import { URI } from '../../../../base/common/uri.js' ;
11
10
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js' ;
12
11
import { ObservableMemento , observableMemento } from '../../../../platform/observable/common/observableMemento.js' ;
@@ -37,7 +36,7 @@ export enum ToolsScope {
37
36
38
37
export class ChatSelectedTools extends Disposable {
39
38
40
- private readonly _selectedTools : ObservableMemento < IToolAndToolSetEnablementMap > ;
39
+ private readonly _selectedTools : ObservableMemento < StoredData > ;
41
40
42
41
private readonly _sessionStates = new ObservableMap < string , IToolAndToolSetEnablementMap | undefined > ( ) ;
43
42
@@ -64,48 +63,8 @@ export class ChatSelectedTools extends Disposable {
64
63
) {
65
64
super ( ) ;
66
65
67
- const storedTools = observableMemento < IToolAndToolSetEnablementMap > ( {
68
- defaultValue : new Map ( ) ,
69
- toStorage : ( value ) => {
70
- const data = {
71
- disabledToolSets : [ ] as string [ ] ,
72
- disabledTools : [ ] as string [ ] ,
73
- } ;
74
- for ( const [ item , enabled ] of value ) {
75
- if ( ! enabled ) {
76
- if ( item instanceof ToolSet ) {
77
- data . disabledToolSets . push ( item . id ) ;
78
- } else {
79
- data . disabledTools . push ( item . id ) ;
80
- }
81
- }
82
- }
83
- return JSON . stringify ( data ) ;
84
- } ,
85
- fromStorage : ( value ) => {
86
- const obj = JSON . parse ( value ) as StoredData ;
87
- const map = new Map < IToolData | ToolSet , boolean > ( ) ;
88
- if ( ! obj || ! isObject ( obj ) ) {
89
- return map ;
90
- }
91
- if ( Array . isArray ( obj . disabledToolSets ) ) {
92
- for ( const toolSetId of obj . disabledToolSets ) {
93
- const toolset = this . _toolsService . getToolSet ( toolSetId ) ;
94
- if ( toolset ) {
95
- map . set ( toolset , false ) ;
96
- }
97
- }
98
- }
99
- if ( Array . isArray ( obj . disabledTools ) ) {
100
- for ( const toolId of obj . disabledTools ) {
101
- const tool = this . _toolsService . getTool ( toolId ) ;
102
- if ( tool ) {
103
- map . set ( tool , false ) ;
104
- }
105
- }
106
- }
107
- return map ;
108
- } ,
66
+ const storedTools = observableMemento < StoredData > ( {
67
+ defaultValue : { disabledToolSets : [ ] , disabledTools : [ ] } ,
109
68
key : 'chat/selectedTools' ,
110
69
} ) ;
111
70
@@ -119,27 +78,36 @@ export class ChatSelectedTools extends Disposable {
119
78
*/
120
79
get entriesMap ( ) : IObservable < IToolAndToolSetEnablementMap > {
121
80
return derived ( r => {
81
+ const map = new Map < IToolData | ToolSet , boolean > ( ) ;
82
+
122
83
const currentMode = this . _mode . read ( r ) ;
123
84
124
85
let currentMap = this . _sessionStates . get ( currentMode . id ) ;
125
- let defaultEnablement = false ;
126
86
if ( ! currentMap && currentMode . kind === ChatModeKind . Agent && currentMode . customTools ) {
127
87
currentMap = this . _toolsService . toToolAndToolSetEnablementMap ( currentMode . customTools . read ( r ) ) ;
128
88
}
129
- if ( ! currentMap ) {
130
- currentMap = this . _selectedTools . read ( r ) ;
131
- defaultEnablement = true ;
132
- }
89
+ if ( currentMap ) {
90
+ for ( const tool of this . _allTools . read ( r ) ) {
91
+ if ( tool . canBeReferencedInPrompt ) {
92
+ map . set ( tool , currentMap . get ( tool ) === true ) ; // false if not present
93
+ }
94
+ }
95
+ for ( const toolSet of this . _toolsService . toolSets . read ( r ) ) {
96
+ map . set ( toolSet , currentMap . get ( toolSet ) === true ) ; // false if not present
97
+ }
98
+ } else {
99
+ const currData = this . _selectedTools . read ( r ) ;
100
+ const disabledToolSets = new Set ( currData . disabledToolSets ?? [ ] ) ;
101
+ const disabledTools = new Set ( currData . disabledTools ?? [ ] ) ;
133
102
134
- // create a complete map of all tools and tool sets
135
- const map = new Map < IToolData | ToolSet , boolean > ( ) ;
136
- const tools = this . _allTools . read ( r ) . filter ( t => t . canBeReferencedInPrompt ) ;
137
- for ( const tool of tools ) {
138
- map . set ( tool , currentMap . get ( tool ) ?? defaultEnablement ) ;
139
- }
140
- const toolSets = this . _toolsService . toolSets . read ( r ) ;
141
- for ( const toolSet of toolSets ) {
142
- map . set ( toolSet , currentMap . get ( toolSet ) ?? defaultEnablement ) ;
103
+ for ( const tool of this . _allTools . read ( r ) ) {
104
+ if ( tool . canBeReferencedInPrompt ) {
105
+ map . set ( tool , ! disabledTools . has ( tool . id ) ) ;
106
+ }
107
+ }
108
+ for ( const toolSet of this . _toolsService . toolSets . read ( r ) ) {
109
+ map . set ( toolSet , ! disabledToolSets . has ( toolSet . id ) ) ;
110
+ }
143
111
}
144
112
return map ;
145
113
} ) ;
@@ -180,7 +148,17 @@ export class ChatSelectedTools extends Disposable {
180
148
this . updateCustomModeTools ( mode . uri . get ( ) , enablementMap ) ;
181
149
return ;
182
150
}
183
- this . _selectedTools . set ( enablementMap , undefined ) ;
151
+ const storedData = { disabledToolSets : [ ] as string [ ] , disabledTools : [ ] as string [ ] } ;
152
+ for ( const [ item , enabled ] of enablementMap ) {
153
+ if ( ! enabled ) {
154
+ if ( item instanceof ToolSet ) {
155
+ storedData . disabledToolSets . push ( item . id ) ;
156
+ } else {
157
+ storedData . disabledTools . push ( item . id ) ;
158
+ }
159
+ }
160
+ }
161
+ this . _selectedTools . set ( storedData , undefined ) ;
184
162
}
185
163
186
164
async updateCustomModeTools ( uri : URI , enablementMap : IToolAndToolSetEnablementMap ) : Promise < void > {
0 commit comments