2025-04-03 19:24:17 -07:00
/ * *
* Copyright ( c ) Microsoft Corporation .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
import { z } from 'zod' ;
2025-04-30 23:06:56 +02:00
import { defineTool , type ToolFactory } from './tool.js' ;
2025-04-03 19:24:17 -07:00
2025-04-22 13:24:38 +02:00
const listTabs = defineTool ( {
2025-04-04 17:14:30 -07:00
capability : 'tabs' ,
2025-04-16 19:36:48 -07:00
2025-04-03 19:24:17 -07:00
schema : {
2025-04-04 15:22:00 -07:00
name : 'browser_tab_list' ,
2025-05-05 17:38:22 -07:00
title : 'List tabs' ,
2025-04-03 19:24:17 -07:00
description : 'List browser tabs' ,
2025-04-22 13:24:38 +02:00
inputSchema : z.object ( { } ) ,
2025-05-05 17:38:22 -07:00
type : 'readOnly' ,
2025-04-03 19:24:17 -07:00
} ,
2025-04-16 19:36:48 -07:00
2025-04-17 00:58:02 -07:00
handle : async context = > {
await context . ensureTab ( ) ;
2025-04-03 19:24:17 -07:00
return {
2025-04-16 19:36:48 -07:00
code : [ ` // <internal code to list tabs> ` ] ,
captureSnapshot : false ,
waitForNetwork : false ,
2025-04-17 00:58:02 -07:00
resultOverride : {
content : [ {
type : 'text' ,
text : await context . listTabsMarkdown ( ) ,
} ] ,
} ,
2025-04-03 19:24:17 -07:00
} ;
} ,
} ) ;
2025-04-22 13:24:38 +02:00
const selectTab : ToolFactory = captureSnapshot = > defineTool ( {
2025-04-04 17:14:30 -07:00
capability : 'tabs' ,
2025-04-16 19:36:48 -07:00
2025-04-03 19:24:17 -07:00
schema : {
2025-04-04 15:22:00 -07:00
name : 'browser_tab_select' ,
2025-05-05 17:38:22 -07:00
title : 'Select a tab' ,
2025-06-19 09:25:48 +00:00
description : 'Select a tab by index (1-based indexing)' ,
2025-04-22 13:24:38 +02:00
inputSchema : z.object ( {
2025-06-19 09:25:48 +00:00
index : z.number ( ) . describe ( 'The index of the tab to select (1-based: first tab is 1, second tab is 2, etc.)' ) ,
2025-04-22 13:24:38 +02:00
} ) ,
2025-05-05 17:38:22 -07:00
type : 'readOnly' ,
2025-04-03 19:24:17 -07:00
} ,
2025-04-16 19:36:48 -07:00
2025-04-03 19:24:17 -07:00
handle : async ( context , params ) = > {
2025-04-22 13:24:38 +02:00
await context . selectTab ( params . index ) ;
2025-04-16 19:36:48 -07:00
const code = [
2025-04-22 13:24:38 +02:00
` // <internal code to select tab ${ params . index } > ` ,
2025-04-16 19:36:48 -07:00
] ;
return {
code ,
captureSnapshot ,
waitForNetwork : false
} ;
2025-04-03 19:24:17 -07:00
} ,
} ) ;
2025-04-22 13:24:38 +02:00
const newTab : ToolFactory = captureSnapshot = > defineTool ( {
2025-04-04 17:14:30 -07:00
capability : 'tabs' ,
2025-04-16 19:36:48 -07:00
2025-04-03 19:24:17 -07:00
schema : {
2025-04-04 15:22:00 -07:00
name : 'browser_tab_new' ,
2025-05-05 17:38:22 -07:00
title : 'Open a new tab' ,
2025-04-03 19:24:17 -07:00
description : 'Open a new tab' ,
2025-04-22 13:24:38 +02:00
inputSchema : z.object ( {
url : z.string ( ) . optional ( ) . describe ( 'The URL to navigate to in the new tab. If not provided, the new tab will be blank.' ) ,
} ) ,
2025-05-05 17:38:22 -07:00
type : 'readOnly' ,
2025-04-03 19:24:17 -07:00
} ,
2025-04-16 19:36:48 -07:00
2025-04-03 19:24:17 -07:00
handle : async ( context , params ) = > {
await context . newTab ( ) ;
2025-04-22 13:24:38 +02:00
if ( params . url )
await context . currentTabOrDie ( ) . navigate ( params . url ) ;
2025-04-16 19:36:48 -07:00
const code = [
` // <internal code to open a new tab> ` ,
] ;
return {
code ,
captureSnapshot ,
waitForNetwork : false
} ;
2025-04-03 19:24:17 -07:00
} ,
2025-04-16 19:36:48 -07:00
} ) ;
2025-04-03 19:24:17 -07:00
2025-04-22 13:24:38 +02:00
const closeTab : ToolFactory = captureSnapshot = > defineTool ( {
2025-04-04 17:14:30 -07:00
capability : 'tabs' ,
2025-04-16 19:36:48 -07:00
2025-04-03 19:24:17 -07:00
schema : {
2025-04-04 15:22:00 -07:00
name : 'browser_tab_close' ,
2025-05-05 17:38:22 -07:00
title : 'Close a tab' ,
2025-04-03 19:24:17 -07:00
description : 'Close a tab' ,
2025-04-22 13:24:38 +02:00
inputSchema : z.object ( {
2025-06-19 09:25:48 +00:00
index : z.number ( ) . optional ( ) . describe ( 'The index of the tab to close (1-based: first tab is 1, second tab is 2, etc.). Closes current tab if not provided.' ) ,
2025-04-22 13:24:38 +02:00
} ) ,
2025-05-05 17:38:22 -07:00
type : 'destructive' ,
2025-04-03 19:24:17 -07:00
} ,
2025-04-16 19:36:48 -07:00
2025-04-03 19:24:17 -07:00
handle : async ( context , params ) = > {
2025-04-22 13:24:38 +02:00
await context . closeTab ( params . index ) ;
2025-04-16 19:36:48 -07:00
const code = [
2025-04-22 13:24:38 +02:00
` // <internal code to close tab ${ params . index } > ` ,
2025-04-16 19:36:48 -07:00
] ;
2025-04-03 19:24:17 -07:00
return {
2025-04-16 19:36:48 -07:00
code ,
captureSnapshot ,
waitForNetwork : false
2025-04-03 19:24:17 -07:00
} ;
} ,
} ) ;
2025-04-04 15:22:00 -07:00
export default ( captureSnapshot : boolean ) = > [
listTabs ,
2025-04-16 19:36:48 -07:00
newTab ( captureSnapshot ) ,
2025-04-04 15:22:00 -07:00
selectTab ( captureSnapshot ) ,
closeTab ( captureSnapshot ) ,
] ;