@@ -65,35 +65,32 @@ export const useScreenshots = ({
6565
6666 let foundBeforeImage = false ;
6767 let foundAfterImage = false ;
68+ let beforeImageData : { url : string ; pageUrl : string | null } | null = null ;
69+ let afterImageData : { url : string ; pageUrl : string | null } | null = null ;
6870
6971 // Search for screenshots BEFORE the current tool call
70- if ( currentStrategy === 'beforeAction' || currentStrategy === 'both' ) {
71- for ( let i = currentToolCallIndex - 1 ; i >= 0 ; i -- ) {
72- const msg = sessionMessages [ i ] ;
73- if ( msg . role === 'environment' && Array . isArray ( msg . content ) ) {
74- const imgContent = msg . content . find (
75- ( c ) => typeof c === 'object' && 'type' in c && c . type === 'image_url' ,
76- ) ;
72+ // Always search for before action image as it may be used as fallback
73+ for ( let i = currentToolCallIndex - 1 ; i >= 0 ; i -- ) {
74+ const msg = sessionMessages [ i ] ;
75+ if ( msg . role === 'environment' && Array . isArray ( msg . content ) ) {
76+ const imgContent = msg . content . find (
77+ ( c ) => typeof c === 'object' && 'type' in c && c . type === 'image_url' ,
78+ ) ;
7779
78- if ( imgContent && 'image_url' in imgContent && imgContent . image_url . url ) {
79- const url =
80- msg . metadata ?. type === 'screenshot' && 'url' in msg . metadata
81- ? msg . metadata . url
82- : null ;
83- setBeforeActionImage ( imgContent . image_url . url ) ;
84- setBeforeActionImageUrl ( url || null ) ;
85- if ( currentStrategy === 'beforeAction' ) {
86- setRelatedImage ( imgContent . image_url . url ) ;
87- setRelatedImageUrl ( url || null ) ;
88- }
89- foundBeforeImage = true ;
90- break ;
91- }
80+ if ( imgContent && 'image_url' in imgContent && imgContent . image_url . url ) {
81+ const url =
82+ msg . metadata ?. type === 'screenshot' && 'url' in msg . metadata ? msg . metadata . url : null ;
83+ beforeImageData = { url : imgContent . image_url . url , pageUrl : url } ;
84+ setBeforeActionImage ( imgContent . image_url . url ) ;
85+ setBeforeActionImageUrl ( url || null ) ;
86+ foundBeforeImage = true ;
87+ break ;
9288 }
9389 }
9490 }
9591
9692 // Search for screenshots AFTER the current tool call
93+ // Always search for after action image as it may be needed for afterAction or both strategies
9794 if ( currentStrategy === 'afterAction' || currentStrategy === 'both' ) {
9895 for ( let i = currentToolCallIndex + 1 ; i < sessionMessages . length ; i ++ ) {
9996 const msg = sessionMessages [ i ] ;
@@ -107,41 +104,56 @@ export const useScreenshots = ({
107104 msg . metadata ?. type === 'screenshot' && 'url' in msg . metadata
108105 ? msg . metadata . url
109106 : null ;
107+ afterImageData = { url : imgContent . image_url . url , pageUrl : url } ;
110108 setAfterActionImage ( imgContent . image_url . url ) ;
111109 setAfterActionImageUrl ( url || null ) ;
112- if ( currentStrategy === 'afterAction' ) {
113- setRelatedImage ( imgContent . image_url . url ) ;
114- setRelatedImageUrl ( url || null ) ;
115- }
116110 foundAfterImage = true ;
117111 break ;
118112 }
119113 }
120114 }
121115 }
122116
123- // Handle strategy-specific warnings and fallbacks
117+ // Handle strategy-specific logic and fallbacks
124118 if ( ! environmentImage ) {
125- if ( currentStrategy === 'beforeAction' && ! foundBeforeImage ) {
126- console . warn (
127- `[BrowserControlRenderer] No valid screenshot found before toolCallId: ${ toolCallId } . Clearing screenshot display.` ,
128- ) ;
129- setRelatedImage ( null ) ;
130- setRelatedImageUrl ( null ) ;
131- } else if ( currentStrategy === 'afterAction' && ! foundAfterImage ) {
132- console . warn (
133- `[BrowserControlRenderer] No valid screenshot found after toolCallId: ${ toolCallId } . Clearing screenshot display.` ,
134- ) ;
135- setRelatedImage ( null ) ;
136- setRelatedImageUrl ( null ) ;
119+ if ( currentStrategy === 'beforeAction' ) {
120+ if ( beforeImageData ) {
121+ setRelatedImage ( beforeImageData . url ) ;
122+ setRelatedImageUrl ( beforeImageData . pageUrl ) ;
123+ } else {
124+ console . warn (
125+ `[BrowserControlRenderer] No valid screenshot found before toolCallId: ${ toolCallId } . Clearing screenshot display.` ,
126+ ) ;
127+ setRelatedImage ( null ) ;
128+ setRelatedImageUrl ( null ) ;
129+ }
130+ } else if ( currentStrategy === 'afterAction' ) {
131+ if ( afterImageData ) {
132+ // Use after action image when available
133+ setRelatedImage ( afterImageData . url ) ;
134+ setRelatedImageUrl ( afterImageData . pageUrl ) ;
135+ } else if ( beforeImageData ) {
136+ // Fallback to before action image to prevent flickering
137+ console . warn (
138+ `[BrowserControlRenderer] No valid screenshot found after toolCallId: ${ toolCallId } . Falling back to before action image.` ,
139+ ) ;
140+ setRelatedImage ( beforeImageData . url ) ;
141+ setRelatedImageUrl ( beforeImageData . pageUrl ) ;
142+ } else {
143+ console . warn (
144+ `[BrowserControlRenderer] No valid screenshots found for toolCallId: ${ toolCallId } . Clearing screenshot display.` ,
145+ ) ;
146+ setRelatedImage ( null ) ;
147+ setRelatedImageUrl ( null ) ;
148+ }
137149 } else if ( currentStrategy === 'both' ) {
138150 // For 'both' strategy, use the after action image as primary if available
139- if ( foundAfterImage ) {
140- setRelatedImage ( afterActionImage ) ;
141- setRelatedImageUrl ( afterActionImageUrl ) ;
142- } else if ( foundBeforeImage ) {
143- setRelatedImage ( beforeActionImage ) ;
144- setRelatedImageUrl ( beforeActionImageUrl ) ;
151+ if ( afterImageData ) {
152+ setRelatedImage ( afterImageData . url ) ;
153+ setRelatedImageUrl ( afterImageData . pageUrl ) ;
154+ } else if ( beforeImageData ) {
155+ setRelatedImage ( beforeImageData . url ) ;
156+ setRelatedImageUrl ( beforeImageData . pageUrl ) ;
145157 } else {
146158 console . warn (
147159 `[BrowserControlRenderer] No valid screenshots found for toolCallId: ${ toolCallId } . Clearing screenshot display.` ,
0 commit comments