@@ -78,6 +78,7 @@ pub enum ConversationAction {
7878 Messages ,
7979 Steer ,
8080 Terminal ,
81+ Browser ,
8182 /// Ends an inter-agent (`agent:`) thread — not a contact block.
8283 End ,
8384}
@@ -91,6 +92,7 @@ impl ConversationAction {
9192 Self :: Messages => "messages" ,
9293 Self :: Steer => "steer" ,
9394 Self :: Terminal => "terminal" ,
95+ Self :: Browser => "browser" ,
9496 Self :: End => "end" ,
9597 }
9698 }
@@ -103,6 +105,19 @@ pub struct TerminalSize {
103105 pub rows : u16 ,
104106}
105107
108+ /// A short-lived capability to watch and drive the browser the conversation's
109+ /// agent handed off: `url` is the runner's screencast WebSocket, `token` the
110+ /// first message's credential. The bearer secrets stay on the platform.
111+ #[ derive( Debug , Clone , Deserialize ) ]
112+ #[ serde( rename_all = "camelCase" ) ]
113+ pub struct BrowserScreencast {
114+ pub session_id : String ,
115+ /// Unix millis.
116+ pub expires_at : u64 ,
117+ pub url : String ,
118+ pub token : String ,
119+ }
120+
106121#[ derive( Debug , thiserror:: Error ) ]
107122pub enum Error {
108123 #[ error( "the OAuth callback was invalid" ) ]
@@ -1147,6 +1162,39 @@ impl Client {
11471162 }
11481163
11491164 /// `/conversations/:identity/terminal[/:terminal_id/:tail]?agentId=`.
1165+ /// Whether the conversation's agent currently has a browser handed off.
1166+ pub async fn browser_available (
1167+ & self ,
1168+ access_token : & str ,
1169+ locator : & ConversationLocator ,
1170+ ) -> Result < bool , Error > {
1171+ #[ derive( Deserialize ) ]
1172+ struct Availability {
1173+ available : bool ,
1174+ }
1175+ let endpoint = self . conversation_endpoint ( locator, Some ( ConversationAction :: Browser ) ) ?;
1176+ let response: Availability = self
1177+ . send_json ( self . http . get ( endpoint) . bearer_auth ( access_token) )
1178+ . await ?;
1179+ Ok ( response. available )
1180+ }
1181+
1182+ /// Mint a screencast capability for the conversation's live browser.
1183+ pub async fn browser_screencast (
1184+ & self ,
1185+ access_token : & str ,
1186+ locator : & ConversationLocator ,
1187+ ) -> Result < BrowserScreencast , Error > {
1188+ let mut endpoint =
1189+ self . conversation_endpoint ( locator, Some ( ConversationAction :: Browser ) ) ?;
1190+ endpoint
1191+ . path_segments_mut ( )
1192+ . map_err ( |_| Error :: InvalidContract ) ?
1193+ . push ( "screencast" ) ;
1194+ self . send_json ( self . http . post ( endpoint) . bearer_auth ( access_token) )
1195+ . await
1196+ }
1197+
11501198 fn terminal_endpoint (
11511199 & self ,
11521200 locator : & ConversationLocator ,
0 commit comments