@@ -71,7 +71,15 @@ describe("filterNativeToolsForMode", () => {
7171 groups : [ "read" , "browser" , "mcp" ] as const ,
7272 }
7373
74- const filtered = filterNativeToolsForMode ( mockNativeTools , "architect" , [ architectMode ] , { } , undefined , { } )
74+ const filtered = filterNativeToolsForMode (
75+ mockNativeTools ,
76+ "architect" ,
77+ [ architectMode ] ,
78+ { } ,
79+ undefined ,
80+ { } ,
81+ undefined ,
82+ )
7583
7684 const toolNames = filtered . map ( ( t ) => ( "function" in t ? t . function . name : "" ) )
7785
@@ -101,7 +109,7 @@ describe("filterNativeToolsForMode", () => {
101109 groups : [ "read" , "edit" , "browser" , "command" , "mcp" ] as const ,
102110 }
103111
104- const filtered = filterNativeToolsForMode ( mockNativeTools , "code" , [ codeMode ] , { } , undefined , { } )
112+ const filtered = filterNativeToolsForMode ( mockNativeTools , "code" , [ codeMode ] , { } , undefined , { } , undefined )
105113
106114 const toolNames = filtered . map ( ( t ) => ( "function" in t ? t . function . name : "" ) )
107115
@@ -123,7 +131,15 @@ describe("filterNativeToolsForMode", () => {
123131 groups : [ ] as const , // No groups
124132 }
125133
126- const filtered = filterNativeToolsForMode ( mockNativeTools , "restrictive" , [ restrictiveMode ] , { } , undefined , { } )
134+ const filtered = filterNativeToolsForMode (
135+ mockNativeTools ,
136+ "restrictive" ,
137+ [ restrictiveMode ] ,
138+ { } ,
139+ undefined ,
140+ { } ,
141+ undefined ,
142+ )
127143
128144 const toolNames = filtered . map ( ( t ) => ( "function" in t ? t . function . name : "" ) )
129145
@@ -138,7 +154,7 @@ describe("filterNativeToolsForMode", () => {
138154 } )
139155
140156 it ( "should handle undefined mode by using default mode" , ( ) => {
141- const filtered = filterNativeToolsForMode ( mockNativeTools , undefined , undefined , { } , undefined , { } )
157+ const filtered = filterNativeToolsForMode ( mockNativeTools , undefined , undefined , { } , undefined , { } , undefined )
142158
143159 // Should return some tools (default mode is code which has all groups)
144160 expect ( filtered . length ) . toBeGreaterThan ( 0 )
@@ -168,11 +184,136 @@ describe("filterNativeToolsForMode", () => {
168184 const toolsWithCodebaseSearch = [ ...mockNativeTools , mockCodebaseSearchTool ]
169185
170186 // Without codeIndexManager
171- const filtered = filterNativeToolsForMode ( toolsWithCodebaseSearch , "code" , [ codeMode ] , { } , undefined , { } )
187+ const filtered = filterNativeToolsForMode (
188+ toolsWithCodebaseSearch ,
189+ "code" ,
190+ [ codeMode ] ,
191+ { } ,
192+ undefined ,
193+ { } ,
194+ undefined ,
195+ )
172196 const toolNames = filtered . map ( ( t ) => ( "function" in t ? t . function . name : "" ) )
173197 expect ( toolNames ) . not . toContain ( "codebase_search" )
174198 } )
175199
200+ it ( "should exclude access_mcp_resource when mcpHub is not provided" , ( ) => {
201+ const codeMode : ModeConfig = {
202+ slug : "code" ,
203+ name : "Code" ,
204+ roleDefinition : "Test" ,
205+ groups : [ "read" , "edit" , "browser" , "command" , "mcp" ] as const ,
206+ }
207+
208+ const mockAccessMcpResourceTool : OpenAI . Chat . ChatCompletionTool = {
209+ type : "function" ,
210+ function : {
211+ name : "access_mcp_resource" ,
212+ description : "Access MCP resource" ,
213+ parameters : { } ,
214+ } ,
215+ }
216+
217+ const toolsWithAccessMcpResource = [ ...mockNativeTools , mockAccessMcpResourceTool ]
218+
219+ // Without mcpHub
220+ const filtered = filterNativeToolsForMode (
221+ toolsWithAccessMcpResource ,
222+ "code" ,
223+ [ codeMode ] ,
224+ { } ,
225+ undefined ,
226+ { } ,
227+ undefined ,
228+ )
229+ const toolNames = filtered . map ( ( t ) => ( "function" in t ? t . function . name : "" ) )
230+ expect ( toolNames ) . not . toContain ( "access_mcp_resource" )
231+ } )
232+
233+ it ( "should exclude access_mcp_resource when mcpHub has no resources" , ( ) => {
234+ const codeMode : ModeConfig = {
235+ slug : "code" ,
236+ name : "Code" ,
237+ roleDefinition : "Test" ,
238+ groups : [ "read" , "edit" , "browser" , "command" , "mcp" ] as const ,
239+ }
240+
241+ const mockAccessMcpResourceTool : OpenAI . Chat . ChatCompletionTool = {
242+ type : "function" ,
243+ function : {
244+ name : "access_mcp_resource" ,
245+ description : "Access MCP resource" ,
246+ parameters : { } ,
247+ } ,
248+ }
249+
250+ const toolsWithAccessMcpResource = [ ...mockNativeTools , mockAccessMcpResourceTool ]
251+
252+ // Mock mcpHub with no resources
253+ const mockMcpHub = {
254+ getServers : ( ) => [
255+ {
256+ name : "test-server" ,
257+ resources : [ ] ,
258+ } ,
259+ ] ,
260+ } as any
261+
262+ const filtered = filterNativeToolsForMode (
263+ toolsWithAccessMcpResource ,
264+ "code" ,
265+ [ codeMode ] ,
266+ { } ,
267+ undefined ,
268+ { } ,
269+ mockMcpHub ,
270+ )
271+ const toolNames = filtered . map ( ( t ) => ( "function" in t ? t . function . name : "" ) )
272+ expect ( toolNames ) . not . toContain ( "access_mcp_resource" )
273+ } )
274+
275+ it ( "should include access_mcp_resource when mcpHub has resources" , ( ) => {
276+ const codeMode : ModeConfig = {
277+ slug : "code" ,
278+ name : "Code" ,
279+ roleDefinition : "Test" ,
280+ groups : [ "read" , "edit" , "browser" , "command" , "mcp" ] as const ,
281+ }
282+
283+ const mockAccessMcpResourceTool : OpenAI . Chat . ChatCompletionTool = {
284+ type : "function" ,
285+ function : {
286+ name : "access_mcp_resource" ,
287+ description : "Access MCP resource" ,
288+ parameters : { } ,
289+ } ,
290+ }
291+
292+ const toolsWithAccessMcpResource = [ ...mockNativeTools , mockAccessMcpResourceTool ]
293+
294+ // Mock mcpHub with resources
295+ const mockMcpHub = {
296+ getServers : ( ) => [
297+ {
298+ name : "test-server" ,
299+ resources : [ { uri : "test://resource" , name : "Test Resource" } ] ,
300+ } ,
301+ ] ,
302+ } as any
303+
304+ const filtered = filterNativeToolsForMode (
305+ toolsWithAccessMcpResource ,
306+ "code" ,
307+ [ codeMode ] ,
308+ { } ,
309+ undefined ,
310+ { } ,
311+ mockMcpHub ,
312+ )
313+ const toolNames = filtered . map ( ( t ) => ( "function" in t ? t . function . name : "" ) )
314+ expect ( toolNames ) . toContain ( "access_mcp_resource" )
315+ } )
316+
176317 it ( "should exclude update_todo_list when todoListEnabled is false" , ( ) => {
177318 const codeMode : ModeConfig = {
178319 slug : "code" ,
@@ -192,9 +333,17 @@ describe("filterNativeToolsForMode", () => {
192333
193334 const toolsWithTodo = [ ...mockNativeTools , mockTodoTool ]
194335
195- const filtered = filterNativeToolsForMode ( toolsWithTodo , "code" , [ codeMode ] , { } , undefined , {
196- todoListEnabled : false ,
197- } )
336+ const filtered = filterNativeToolsForMode (
337+ toolsWithTodo ,
338+ "code" ,
339+ [ codeMode ] ,
340+ { } ,
341+ undefined ,
342+ {
343+ todoListEnabled : false ,
344+ } ,
345+ undefined ,
346+ )
198347 const toolNames = filtered . map ( ( t ) => ( "function" in t ? t . function . name : "" ) )
199348 expect ( toolNames ) . not . toContain ( "update_todo_list" )
200349 } )
@@ -225,6 +374,7 @@ describe("filterNativeToolsForMode", () => {
225374 { imageGeneration : false } ,
226375 undefined ,
227376 { } ,
377+ undefined ,
228378 )
229379 const toolNames = filtered . map ( ( t ) => ( "function" in t ? t . function . name : "" ) )
230380 expect ( toolNames ) . not . toContain ( "generate_image" )
@@ -256,6 +406,7 @@ describe("filterNativeToolsForMode", () => {
256406 { runSlashCommand : false } ,
257407 undefined ,
258408 { } ,
409+ undefined ,
259410 )
260411 const toolNames = filtered . map ( ( t ) => ( "function" in t ? t . function . name : "" ) )
261412 expect ( toolNames ) . not . toContain ( "run_slash_command" )
0 commit comments