pub struct ComputerUse { /* private fields */ }Expand description
Complete app-scoped computer-use harness.
Implementations§
Source§impl ComputerUse
impl ComputerUse
Sourcepub fn new() -> Result<Self>
pub fn new() -> Result<Self>
Start a harness with production defaults.
Examples found in repository?
examples/agent_loop.rs (line 21)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11 let mut args = env::args().skip(1);
12 let program = args
13 .next()
14 .unwrap_or_else(|| "gnome-calculator".to_string());
15
16 let mut config = LaunchConfig::new(&program);
17 for extra in args {
18 config = config.arg(extra);
19 }
20
21 let harness = ComputerUse::new()?;
22 let mut app = harness.launch(config)?;
23 println!("launched {program} via {:?}", app.transport());
24
25 // 1. Perceive: capture the initial frame.
26 let before = app.capture()?;
27 before.image.save("agent-loop-before.png")?;
28 println!(
29 "captured {}x{} -> agent-loop-before.png",
30 before.image.width(),
31 before.image.height()
32 );
33
34 // 2. Act: focus, select-all, and type, exercising keyboard + text paths.
35 app.click(
36 before.image.width() as f64 / 2.0,
37 before.image.height() as f64 / 2.0,
38 PointerButton::Left,
39 1,
40 )?;
41 app.press_key("ctrl+a")?;
42 app.type_text("agent-seat-linux")?;
43
44 // 3. Perceive again: capture the post-action frame.
45 let after = app.capture()?;
46 after.image.save("agent-loop-after.png")?;
47 println!(
48 "captured {}x{} -> agent-loop-after.png",
49 after.image.width(),
50 after.image.height()
51 );
52
53 // 4. Teardown: stop the app, then close the seat.
54 app.stop();
55 harness.close();
56 println!("done");
57 Ok(())
58}Sourcepub fn builder() -> ComputerUseBuilder
pub fn builder() -> ComputerUseBuilder
Configure launch timeouts and bridge geometry.
Examples found in repository?
examples/basic.rs (line 10)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let mut arguments = std::env::args_os().skip(1);
7 let program = arguments
8 .next()
9 .unwrap_or_else(|| "gnome-calculator".into());
10 let harness = ComputerUse::builder()
11 .native_timeout(Duration::from_secs(8))
12 .fallback_timeout(Duration::from_secs(30))
13 .bridge_geometry(1280, 800)
14 .build()?;
15 let mut app = harness.launch(LaunchConfig::new(program).args(arguments))?;
16
17 let frame = app.capture()?;
18 println!(
19 "controlled pid={} transport={:?} frame={}x{}",
20 app.pid(),
21 app.transport(),
22 frame.width,
23 frame.height
24 );
25 frame.image.save("agent-seat-frame.png")?;
26
27 // Harmlessly focus the center of the captured app to prove pointer input.
28 app.click(
29 f64::from(frame.width) / 2.0,
30 f64::from(frame.height) / 2.0,
31 PointerButton::Left,
32 1,
33 )?;
34
35 app.stop();
36 Ok(())
37}Sourcepub fn socket_name(&self) -> String
pub fn socket_name(&self) -> String
The private WAYLAND_DISPLAY socket, for advanced integrations.
Sourcepub fn launch(&self, config: LaunchConfig) -> Result<ControlledApp>
pub fn launch(&self, config: LaunchConfig) -> Result<ControlledApp>
Launch and bind an application. Native Wayland is tried first. If the application does not expose a readable app-sized frame, the same launch is retried through an authenticated XWayland bridge automatically.
Examples found in repository?
examples/basic.rs (line 15)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let mut arguments = std::env::args_os().skip(1);
7 let program = arguments
8 .next()
9 .unwrap_or_else(|| "gnome-calculator".into());
10 let harness = ComputerUse::builder()
11 .native_timeout(Duration::from_secs(8))
12 .fallback_timeout(Duration::from_secs(30))
13 .bridge_geometry(1280, 800)
14 .build()?;
15 let mut app = harness.launch(LaunchConfig::new(program).args(arguments))?;
16
17 let frame = app.capture()?;
18 println!(
19 "controlled pid={} transport={:?} frame={}x{}",
20 app.pid(),
21 app.transport(),
22 frame.width,
23 frame.height
24 );
25 frame.image.save("agent-seat-frame.png")?;
26
27 // Harmlessly focus the center of the captured app to prove pointer input.
28 app.click(
29 f64::from(frame.width) / 2.0,
30 f64::from(frame.height) / 2.0,
31 PointerButton::Left,
32 1,
33 )?;
34
35 app.stop();
36 Ok(())
37}More examples
examples/agent_loop.rs (line 22)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11 let mut args = env::args().skip(1);
12 let program = args
13 .next()
14 .unwrap_or_else(|| "gnome-calculator".to_string());
15
16 let mut config = LaunchConfig::new(&program);
17 for extra in args {
18 config = config.arg(extra);
19 }
20
21 let harness = ComputerUse::new()?;
22 let mut app = harness.launch(config)?;
23 println!("launched {program} via {:?}", app.transport());
24
25 // 1. Perceive: capture the initial frame.
26 let before = app.capture()?;
27 before.image.save("agent-loop-before.png")?;
28 println!(
29 "captured {}x{} -> agent-loop-before.png",
30 before.image.width(),
31 before.image.height()
32 );
33
34 // 2. Act: focus, select-all, and type, exercising keyboard + text paths.
35 app.click(
36 before.image.width() as f64 / 2.0,
37 before.image.height() as f64 / 2.0,
38 PointerButton::Left,
39 1,
40 )?;
41 app.press_key("ctrl+a")?;
42 app.type_text("agent-seat-linux")?;
43
44 // 3. Perceive again: capture the post-action frame.
45 let after = app.capture()?;
46 after.image.save("agent-loop-after.png")?;
47 println!(
48 "captured {}x{} -> agent-loop-after.png",
49 after.image.width(),
50 after.image.height()
51 );
52
53 // 4. Teardown: stop the app, then close the seat.
54 app.stop();
55 harness.close();
56 println!("done");
57 Ok(())
58}Sourcepub fn close(&self)
pub fn close(&self)
Explicitly stop the seat and every compatibility bridge.
Examples found in repository?
examples/agent_loop.rs (line 55)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11 let mut args = env::args().skip(1);
12 let program = args
13 .next()
14 .unwrap_or_else(|| "gnome-calculator".to_string());
15
16 let mut config = LaunchConfig::new(&program);
17 for extra in args {
18 config = config.arg(extra);
19 }
20
21 let harness = ComputerUse::new()?;
22 let mut app = harness.launch(config)?;
23 println!("launched {program} via {:?}", app.transport());
24
25 // 1. Perceive: capture the initial frame.
26 let before = app.capture()?;
27 before.image.save("agent-loop-before.png")?;
28 println!(
29 "captured {}x{} -> agent-loop-before.png",
30 before.image.width(),
31 before.image.height()
32 );
33
34 // 2. Act: focus, select-all, and type, exercising keyboard + text paths.
35 app.click(
36 before.image.width() as f64 / 2.0,
37 before.image.height() as f64 / 2.0,
38 PointerButton::Left,
39 1,
40 )?;
41 app.press_key("ctrl+a")?;
42 app.type_text("agent-seat-linux")?;
43
44 // 3. Perceive again: capture the post-action frame.
45 let after = app.capture()?;
46 after.image.save("agent-loop-after.png")?;
47 println!(
48 "captured {}x{} -> agent-loop-after.png",
49 after.image.width(),
50 after.image.height()
51 );
52
53 // 4. Teardown: stop the app, then close the seat.
54 app.stop();
55 harness.close();
56 println!("done");
57 Ok(())
58}Trait Implementations§
Source§impl Drop for ComputerUse
impl Drop for ComputerUse
Auto Trait Implementations§
impl Freeze for ComputerUse
impl RefUnwindSafe for ComputerUse
impl Send for ComputerUse
impl Sync for ComputerUse
impl Unpin for ComputerUse
impl UnsafeUnpin for ComputerUse
impl UnwindSafe for ComputerUse
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Convert
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Convert
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
Convert
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
Convert
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.