@@ -81,8 +81,6 @@ def __init__(
8181 self .config = config or AgentConfig ()
8282
8383 # Screenshot sequence counter
84- self ._screenshot_sequence = 0
85-
8684 # Execution history
8785 self .history : list [dict [str , Any ]] = []
8886
@@ -174,21 +172,6 @@ def act( # noqa: C901
174172 if snap .status != "success" :
175173 raise RuntimeError (f"Snapshot failed: { snap .error } " )
176174
177- # Store screenshot if captured
178- if snap .screenshot and self .tracer :
179- self ._screenshot_sequence += 1
180- seq = self ._screenshot_sequence
181-
182- # Store screenshot in CloudTraceSink if available
183- if hasattr (self .tracer .sink , "store_screenshot" ):
184- self .tracer .sink .store_screenshot (
185- sequence = seq ,
186- screenshot_data = snap .screenshot ,
187- format = snap .screenshot_format
188- or (self .config .screenshot_format if self .config else "jpeg" ),
189- step_id = step_id ,
190- )
191-
192175 # Apply element filtering based on goal
193176 filtered_elements = self .filter_elements (snap , goal )
194177
@@ -211,14 +194,36 @@ def act( # noqa: C901
211194 for el in filtered_elements [:50 ] # Limit to first 50 for performance
212195 ]
213196
197+ # Build snapshot event data
198+ snapshot_data = {
199+ "url" : snap .url ,
200+ "element_count" : len (snap .elements ),
201+ "timestamp" : snap .timestamp ,
202+ "elements" : elements_data , # Add element data for overlay
203+ }
204+
205+ # Always include screenshot in trace event for studio viewer compatibility
206+ # CloudTraceSink will extract and upload screenshots separately, then remove
207+ # screenshot_base64 from events before uploading the trace file.
208+ if snap .screenshot :
209+ # Extract base64 string from data URL if needed
210+ if snap .screenshot .startswith ("data:image" ):
211+ # Format: "data:image/jpeg;base64,{base64_string}"
212+ screenshot_base64 = (
213+ snap .screenshot .split ("," , 1 )[1 ]
214+ if "," in snap .screenshot
215+ else snap .screenshot
216+ )
217+ else :
218+ screenshot_base64 = snap .screenshot
219+
220+ snapshot_data ["screenshot_base64" ] = screenshot_base64
221+ if snap .screenshot_format :
222+ snapshot_data ["screenshot_format" ] = snap .screenshot_format
223+
214224 self .tracer .emit (
215225 "snapshot" ,
216- {
217- "url" : snap .url ,
218- "element_count" : len (snap .elements ),
219- "timestamp" : snap .timestamp ,
220- "elements" : elements_data , # Add element data for overlay
221- },
226+ snapshot_data ,
222227 step_id = step_id ,
223228 )
224229
@@ -757,8 +762,6 @@ def __init__(
757762 self .config = config or AgentConfig ()
758763
759764 # Screenshot sequence counter
760- self ._screenshot_sequence = 0
761-
762765 # Execution history
763766 self .history : list [dict [str , Any ]] = []
764767
@@ -847,21 +850,6 @@ async def act( # noqa: C901
847850 if snap .status != "success" :
848851 raise RuntimeError (f"Snapshot failed: { snap .error } " )
849852
850- # Store screenshot if captured
851- if snap .screenshot and self .tracer :
852- self ._screenshot_sequence += 1
853- seq = self ._screenshot_sequence
854-
855- # Store screenshot in CloudTraceSink if available
856- if hasattr (self .tracer .sink , "store_screenshot" ):
857- self .tracer .sink .store_screenshot (
858- sequence = seq ,
859- screenshot_data = snap .screenshot ,
860- format = snap .screenshot_format
861- or (self .config .screenshot_format if self .config else "jpeg" ),
862- step_id = step_id ,
863- )
864-
865853 # Apply element filtering based on goal
866854 filtered_elements = self .filter_elements (snap , goal )
867855
@@ -884,14 +872,36 @@ async def act( # noqa: C901
884872 for el in filtered_elements [:50 ] # Limit to first 50 for performance
885873 ]
886874
875+ # Build snapshot event data
876+ snapshot_data = {
877+ "url" : snap .url ,
878+ "element_count" : len (snap .elements ),
879+ "timestamp" : snap .timestamp ,
880+ "elements" : elements_data , # Add element data for overlay
881+ }
882+
883+ # Always include screenshot in trace event for studio viewer compatibility
884+ # CloudTraceSink will extract and upload screenshots separately, then remove
885+ # screenshot_base64 from events before uploading the trace file.
886+ if snap .screenshot :
887+ # Extract base64 string from data URL if needed
888+ if snap .screenshot .startswith ("data:image" ):
889+ # Format: "data:image/jpeg;base64,{base64_string}"
890+ screenshot_base64 = (
891+ snap .screenshot .split ("," , 1 )[1 ]
892+ if "," in snap .screenshot
893+ else snap .screenshot
894+ )
895+ else :
896+ screenshot_base64 = snap .screenshot
897+
898+ snapshot_data ["screenshot_base64" ] = screenshot_base64
899+ if snap .screenshot_format :
900+ snapshot_data ["screenshot_format" ] = snap .screenshot_format
901+
887902 self .tracer .emit (
888903 "snapshot" ,
889- {
890- "url" : snap .url ,
891- "element_count" : len (snap .elements ),
892- "timestamp" : snap .timestamp ,
893- "elements" : elements_data , # Add element data for overlay
894- },
904+ snapshot_data ,
895905 step_id = step_id ,
896906 )
897907
0 commit comments