@@ -6,41 +6,35 @@ import { errorToString } from '../../utils/errorToString.js';
66import { sleep } from '../../utils/sleep.js' ;
77
88import { filterPageContent } from './filterPageContent.js' ;
9- import { browserSessions , type BrowserAction , SelectorType } from './types.js' ;
10-
11- // Schema for browser action
12- const browserActionSchema = z
13- . object ( {
14- actionType : z . enum ( [ 'goto' , 'click' , 'type' , 'wait' , 'content' , 'close' ] ) ,
15- url : z
16- . string ( )
17- . url ( )
18- . optional ( )
19- . describe ( 'URL to navigate to if "goto" actionType' ) ,
20- selector : z
21- . string ( )
22- . optional ( )
23- . describe ( 'Selector to click if "click" actionType' ) ,
24- selectorType : z
25- . nativeEnum ( SelectorType )
26- . optional ( )
27- . describe ( 'Type of selector if "click" actionType' ) ,
28- text : z
29- . string ( )
30- . optional ( )
31- . describe (
32- 'Text to type if "type" actionType, for other actionType, this is ignored' ,
33- ) ,
34- } )
35- . describe ( 'Browser action to perform' ) ;
9+ import { browserSessions , SelectorType } from './types.js' ;
3610
3711// Main parameter schema
3812const parameterSchema = z . object ( {
3913 instanceId : z . string ( ) . describe ( 'The ID returned by browseStart' ) ,
40- action : browserActionSchema ,
14+ actionType : z
15+ . enum ( [ 'goto' , 'click' , 'type' , 'wait' , 'content' , 'close' ] )
16+ . describe ( 'Browser action to perform' ) ,
17+ url : z
18+ . string ( )
19+ . url ( )
20+ . optional ( )
21+ . describe ( 'URL to navigate to if "goto" actionType' ) ,
22+ selector : z
23+ . string ( )
24+ . optional ( )
25+ . describe ( 'Selector to click if "click" actionType' ) ,
26+ selectorType : z
27+ . nativeEnum ( SelectorType )
28+ . optional ( )
29+ . describe ( 'Type of selector if "click" actionType' ) ,
30+ text : z
31+ . string ( )
32+ . optional ( )
33+ . describe (
34+ 'Text to type if "type" actionType, for other actionType, this is ignored' ,
35+ ) ,
4136 description : z
4237 . string ( )
43- . max ( 80 )
4438 . describe ( 'The reason for this browser action (max 80 chars)' ) ,
4539} ) ;
4640
@@ -76,27 +70,20 @@ export const browseMessageTool: Tool<Parameters, ReturnType> = {
7670 returnsJsonSchema : zodToJsonSchema ( returnSchema ) ,
7771
7872 execute : async (
79- { instanceId, action } ,
73+ { instanceId, actionType , url , selector , selectorType , text } ,
8074 { logger, pageFilter } ,
8175 ) : Promise < ReturnType > => {
8276 // Validate action format
83- if ( ! action || typeof action !== 'object' ) {
84- logger . error ( 'Invalid action format: action must be an object' ) ;
85- return {
86- status : 'error' ,
87- error : 'Invalid action format: action must be an object' ,
88- } ;
89- }
9077
91- if ( ! action . actionType ) {
78+ if ( ! actionType ) {
9279 logger . error ( 'Invalid action format: actionType is required' ) ;
9380 return {
9481 status : 'error' ,
9582 error : 'Invalid action format: actionType is required' ,
9683 } ;
9784 }
9885
99- logger . verbose ( `Executing browser action: ${ action . actionType } ` ) ;
86+ logger . verbose ( `Executing browser action: ${ actionType } ` ) ;
10087 logger . verbose ( `Webpage processing mode: ${ pageFilter } ` ) ;
10188
10289 try {
@@ -107,18 +94,18 @@ export const browseMessageTool: Tool<Parameters, ReturnType> = {
10794
10895 const { page } = session ;
10996
110- switch ( action . actionType ) {
97+ switch ( actionType ) {
11198 case 'goto' : {
112- if ( ! action . url ) {
99+ if ( ! url ) {
113100 throw new Error ( 'URL required for goto action' ) ;
114101 }
115102
116103 try {
117104 // Try with 'domcontentloaded' first which is more reliable than 'networkidle'
118105 logger . verbose (
119- `Navigating to ${ action . url } with 'domcontentloaded' waitUntil` ,
106+ `Navigating to ${ url } with 'domcontentloaded' waitUntil` ,
120107 ) ;
121- await page . goto ( action . url , { waitUntil : 'domcontentloaded' } ) ;
108+ await page . goto ( url , { waitUntil : 'domcontentloaded' } ) ;
122109 await sleep ( 3000 ) ;
123110 const content = await filterPageContent ( page , pageFilter ) ;
124111 logger . verbose ( `Content: ${ content } ` ) ;
@@ -133,11 +120,11 @@ export const browseMessageTool: Tool<Parameters, ReturnType> = {
133120 `Failed with domcontentloaded strategy: ${ errorToString ( navError ) } ` ,
134121 ) ;
135122 logger . verbose (
136- `Retrying navigation to ${ action . url } with no waitUntil option` ,
123+ `Retrying navigation to ${ url } with no waitUntil option` ,
137124 ) ;
138125
139126 try {
140- await page . goto ( action . url ) ;
127+ await page . goto ( url ) ;
141128 await sleep ( 3000 ) ;
142129 const content = await filterPageContent ( page , pageFilter ) ;
143130 logger . verbose ( `Content: ${ content } ` ) ;
@@ -153,13 +140,10 @@ export const browseMessageTool: Tool<Parameters, ReturnType> = {
153140 }
154141
155142 case 'click' : {
156- if ( ! action . selector ) {
143+ if ( ! selector ) {
157144 throw new Error ( 'Selector required for click action' ) ;
158145 }
159- const clickSelector = getSelector (
160- action . selector ,
161- action . selectorType ,
162- ) ;
146+ const clickSelector = getSelector ( selector , selectorType ) ;
163147 await page . click ( clickSelector ) ;
164148 await sleep ( 1000 ) ; // Wait for any content changes after click
165149 const content = await filterPageContent ( page , pageFilter ) ;
@@ -170,26 +154,20 @@ export const browseMessageTool: Tool<Parameters, ReturnType> = {
170154 }
171155
172156 case 'type' : {
173- if ( ! action . selector || ! action . text ) {
157+ if ( ! selector || ! text ) {
174158 throw new Error ( 'Selector and text required for type action' ) ;
175159 }
176- const typeSelector = getSelector (
177- action . selector ,
178- action . selectorType ,
179- ) ;
180- await page . fill ( typeSelector , action . text ) ;
160+ const typeSelector = getSelector ( selector , selectorType ) ;
161+ await page . fill ( typeSelector , text ) ;
181162 logger . verbose ( `Type action completed on selector: ${ typeSelector } ` ) ;
182163 return { status : 'success' } ;
183164 }
184165
185166 case 'wait' : {
186- if ( ! action . selector ) {
167+ if ( ! selector ) {
187168 throw new Error ( 'Selector required for wait action' ) ;
188169 }
189- const waitSelector = getSelector (
190- action . selector ,
191- action . selectorType ,
192- ) ;
170+ const waitSelector = getSelector ( selector , selectorType ) ;
193171 await page . waitForSelector ( waitSelector ) ;
194172 logger . verbose ( `Wait action completed for selector: ${ waitSelector } ` ) ;
195173 return { status : 'success' } ;
@@ -211,9 +189,7 @@ export const browseMessageTool: Tool<Parameters, ReturnType> = {
211189 }
212190
213191 default : {
214- throw new Error (
215- `Unsupported action type: ${ ( action as BrowserAction ) . actionType } ` ,
216- ) ;
192+ throw new Error ( `Unsupported action type: ${ actionType } ` ) ;
217193 }
218194 }
219195 } catch ( error ) {
@@ -226,11 +202,11 @@ export const browseMessageTool: Tool<Parameters, ReturnType> = {
226202 } ,
227203
228204 logParameters : (
229- { action , description } ,
205+ { actionType , description } ,
230206 { logger, pageFilter = 'simple' } ,
231207 ) => {
232208 logger . info (
233- `Performing browser action: ${ action . actionType } with ${ pageFilter } processing, ${ description } ` ,
209+ `Performing browser action: ${ actionType } with ${ pageFilter } processing, ${ description } ` ,
234210 ) ;
235211 } ,
236212
0 commit comments