chore: seed sgclaw rust baseline

This commit is contained in:
zyl
2026-03-25 02:17:55 +00:00
parent 5063adc530
commit 8757bbb266
26 changed files with 2825 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
use std::io::{Cursor, Result as IoResult, Write};
use std::sync::{Arc, Mutex};
use std::time::Duration;
use sgclaw::pipe::{
perform_handshake, Action, AgentMessage, BrowserPipeTool, StdioTransport, Timing,
};
use sgclaw::security::MacPolicy;
#[derive(Clone, Default)]
struct SharedBuffer {
inner: Arc<Mutex<Vec<u8>>>,
}
impl SharedBuffer {
fn snapshot(&self) -> String {
String::from_utf8(self.inner.lock().unwrap().clone()).unwrap()
}
}
impl Write for SharedBuffer {
fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
self.inner.lock().unwrap().extend_from_slice(buf);
Ok(buf.len())
}
fn flush(&mut self) -> IoResult<()> {
Ok(())
}
}
#[test]
fn handshake_and_command_flow_work_over_json_line_transport() {
let reader = Cursor::new(
concat!(
r#"{"type":"init","version":"1.0","hmac_seed":"0123456789abcdef","capabilities":["browser_action"]}"#,
"\n",
r#"{"type":"response","seq":1,"success":true,"data":{"text":"提交成功"},"aom_snapshot":[],"timing":{"queue_ms":2,"exec_ms":38}}"#,
"\n"
)
.as_bytes()
.to_vec(),
);
let writer = SharedBuffer::default();
let captured = writer.clone();
let transport = Arc::new(StdioTransport::new(reader, writer));
let handshake = perform_handshake(transport.as_ref(), Duration::from_secs(1)).unwrap();
let policy = MacPolicy::from_json_str(
r#"{
"version": "1.0",
"domains": { "allowed": ["oa.example.com"] },
"pipe_actions": {
"allowed": ["click", "type", "navigate", "getText"],
"blocked": []
}
}"#,
)
.unwrap();
let tool = BrowserPipeTool::new(transport, policy, handshake.session_key)
.with_response_timeout(Duration::from_secs(1));
let result = tool
.invoke(
Action::Click,
serde_json::json!({ "selector": "#submit" }),
"oa.example.com",
)
.unwrap();
let written = captured.snapshot();
assert_eq!(
result.timing,
Timing {
queue_ms: 2,
exec_ms: 38
}
);
assert!(written.contains(r#""type":"init_ack""#));
assert!(written.contains(r#""type":"command""#));
assert!(written.contains(r#""action":"click""#));
let lines: Vec<&str> = written.lines().collect();
let command: AgentMessage = serde_json::from_str(lines[1]).unwrap();
assert!(matches!(
command,
AgentMessage::Command { seq, .. } if seq == 1
));
}