@@ -29,6 +29,7 @@ export class StagehandActHandler {
29
29
[ key : string ] : { result : string ; action : string } ;
30
30
} ;
31
31
private readonly userProvidedInstructions ?: string ;
32
+ private readonly selfHeal : boolean ;
32
33
33
34
constructor ( {
34
35
verbose,
@@ -37,6 +38,7 @@ export class StagehandActHandler {
37
38
logger,
38
39
stagehandPage,
39
40
userProvidedInstructions,
41
+ selfHeal,
40
42
} : {
41
43
verbose : 0 | 1 | 2 ;
42
44
llmProvider : LLMProvider ;
@@ -46,6 +48,7 @@ export class StagehandActHandler {
46
48
stagehandPage : StagehandPage ;
47
49
stagehandContext : StagehandContext ;
48
50
userProvidedInstructions ?: string ;
51
+ selfHeal : boolean ;
49
52
} ) {
50
53
this . verbose = verbose ;
51
54
this . llmProvider = llmProvider ;
@@ -55,6 +58,7 @@ export class StagehandActHandler {
55
58
this . actions = { } ;
56
59
this . stagehandPage = stagehandPage ;
57
60
this . userProvidedInstructions = userProvidedInstructions ;
61
+ this . selfHeal = selfHeal ;
58
62
}
59
63
60
64
/**
@@ -90,21 +94,61 @@ export class StagehandActHandler {
90
94
action : observe . description || `ObserveResult action (${ method } )` ,
91
95
} ;
92
96
} catch ( err ) {
97
+ if ( ! this . selfHeal ) {
98
+ this . logger ( {
99
+ category : "action" ,
100
+ message : "Error performing act from an ObserveResult" ,
101
+ level : 1 ,
102
+ auxiliary : {
103
+ error : { value : err . message , type : "string" } ,
104
+ trace : { value : err . stack , type : "string" } ,
105
+ } ,
106
+ } ) ;
107
+ return {
108
+ success : false ,
109
+ message : `Failed to perform act: ${ err . message } ` ,
110
+ action : observe . description || `ObserveResult action (${ method } )` ,
111
+ } ;
112
+ }
113
+ // We will try to use regular act on a failed ObserveResult-act if selfHeal is true
93
114
this . logger ( {
94
115
category : "action" ,
95
- message : "Error performing act from an ObserveResult" ,
116
+ message :
117
+ "Error performing act from an ObserveResult. Trying again with regular act method" ,
96
118
level : 1 ,
97
119
auxiliary : {
98
120
error : { value : err . message , type : "string" } ,
99
121
trace : { value : err . stack , type : "string" } ,
100
122
observeResult : { value : JSON . stringify ( observe ) , type : "object" } ,
101
123
} ,
102
124
} ) ;
103
- return {
104
- success : false ,
105
- message : `Failed to perform act: ${ err . message } ` ,
106
- action : observe . description || `ObserveResult action (${ method } )` ,
107
- } ;
125
+ try {
126
+ // Remove redundancy from method-description
127
+ const actCommand = observe . description
128
+ . toLowerCase ( )
129
+ . startsWith ( method . toLowerCase ( ) )
130
+ ? observe . description
131
+ : method
132
+ ? `${ method } ${ observe . description } `
133
+ : observe . description ;
134
+ // Call act with the ObserveResult description
135
+ await this . stagehandPage . act ( actCommand ) ;
136
+ } catch ( err ) {
137
+ this . logger ( {
138
+ category : "action" ,
139
+ message : "Error performing act from an ObserveResult" ,
140
+ level : 1 ,
141
+ auxiliary : {
142
+ error : { value : err . message , type : "string" } ,
143
+ trace : { value : err . stack , type : "string" } ,
144
+ } ,
145
+ } ) ;
146
+ return {
147
+ success : false ,
148
+ message : `Failed to perform act: ${ err . message } ` ,
149
+ action : observe . description || `ObserveResult action (${ method } )` ,
150
+ } ;
151
+ }
108
152
}
109
153
}
110
154
@@ -369,7 +413,7 @@ export class StagehandActHandler {
369
413
const clickArg = args . length ? args [ 0 ] : undefined ;
370
414
371
415
if ( isRadio ) {
372
- // if it’ s a radio button, try to find a label to click
416
+ // if it' s a radio button, try to find a label to click
373
417
const inputId = await locator . evaluate ( ( el ) => el . id ) ;
374
418
let labelLocator ;
375
419
@@ -380,7 +424,7 @@ export class StagehandActHandler {
380
424
) ;
381
425
}
382
426
if ( ! labelLocator || ( await labelLocator . count ( ) ) < 1 ) {
383
- // if no label was found or the label doesn’ t exist, check if
427
+ // if no label was found or the label doesn' t exist, check if
384
428
// there is an ancestor <label>
385
429
labelLocator = this . stagehandPage . page
386
430
. locator ( `xpath=${ xpath } /ancestor::label` )
0 commit comments