feat: add websocket browser service runtime
Wire the service/browser runtime onto the websocket-driven execution path and add the new browser/service modules needed for the submit flow and runtime integration. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
78
src/bin/sg_claw_client.rs
Normal file
78
src/bin/sg_claw_client.rs
Normal file
@@ -0,0 +1,78 @@
|
||||
use std::io::{self, BufRead};
|
||||
|
||||
use sgclaw::service::{ClientMessage, ServiceMessage};
|
||||
use tungstenite::{connect, Message};
|
||||
|
||||
fn main() -> std::process::ExitCode {
|
||||
match run() {
|
||||
Ok(()) => std::process::ExitCode::SUCCESS,
|
||||
Err(err) => {
|
||||
eprintln!("sg_claw_client failed: {err}");
|
||||
std::process::ExitCode::FAILURE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_request(input: &str) -> (ClientMessage, bool) {
|
||||
match input.trim() {
|
||||
"/connect" => (ClientMessage::Connect, true),
|
||||
"/start" => (ClientMessage::Start, true),
|
||||
"/stop" => (ClientMessage::Stop, true),
|
||||
instruction => (
|
||||
ClientMessage::SubmitTask {
|
||||
instruction: instruction.to_string(),
|
||||
conversation_id: String::new(),
|
||||
messages: vec![],
|
||||
page_url: String::new(),
|
||||
page_title: String::new(),
|
||||
},
|
||||
false,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<(), String> {
|
||||
let service_url = std::env::var("SG_CLAW_SERVICE_WS_URL")
|
||||
.unwrap_or_else(|_| "ws://127.0.0.1:42321".to_string());
|
||||
let (mut socket, _) = connect(service_url.as_str()).map_err(|err| err.to_string())?;
|
||||
|
||||
let mut input = String::new();
|
||||
io::stdin()
|
||||
.lock()
|
||||
.read_line(&mut input)
|
||||
.map_err(|err| err.to_string())?;
|
||||
|
||||
let (request, exit_on_status) = parse_request(&input);
|
||||
|
||||
let payload = serde_json::to_string(&request).map_err(|err| err.to_string())?;
|
||||
socket
|
||||
.send(Message::Text(payload.into()))
|
||||
.map_err(|err| err.to_string())?;
|
||||
|
||||
loop {
|
||||
match socket.read().map_err(|err| err.to_string())? {
|
||||
Message::Text(text) => {
|
||||
let message: ServiceMessage =
|
||||
serde_json::from_str(&text).map_err(|err| err.to_string())?;
|
||||
match message {
|
||||
ServiceMessage::StatusChanged { state } => {
|
||||
println!("status: {state}");
|
||||
if exit_on_status {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
ServiceMessage::LogEntry { level: _, message } => {
|
||||
println!("{message}");
|
||||
}
|
||||
ServiceMessage::TaskComplete { success: _, summary } => {
|
||||
println!("{summary}");
|
||||
return Ok(());
|
||||
}
|
||||
ServiceMessage::Busy { message } => return Err(message),
|
||||
}
|
||||
}
|
||||
Message::Close(_) => return Err("service disconnected before task completion".to_string()),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user