A live-model e2e: any OpenAI-compatible brain must drive a shell turn (gated by env)
This commit is contained in:
parent
ef44db4645
commit
6f8568d16b
51
src/agent.rs
51
src/agent.rs
|
|
@ -2421,6 +2421,57 @@ mod tests {
|
|||
/// a box: `ANYBOT_DATA_DIR=<scratch> cargo test --release -- --ignored
|
||||
/// a_brain_without_chrome_browses_on_its_box --nocapture`.
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn real_model_drives_a_shell_turn() {
|
||||
// A real brain, end to end: point it at any OpenAI-compatible endpoint with
|
||||
// ANYBOT_LIVE_BASE / ANYBOT_LIVE_KEY / ANYBOT_LIVE_MODEL and run
|
||||
// `cargo test real_model_drives -- --ignored --nocapture`. It asks the model to write
|
||||
// a file and read it back; the turn must survive real tool calls, not a script.
|
||||
let Ok(base) = std::env::var("ANYBOT_LIVE_BASE") else { eprintln!("no ANYBOT_LIVE_BASE; skipped"); return };
|
||||
let key = std::env::var("ANYBOT_LIVE_KEY").unwrap_or_default();
|
||||
let model = std::env::var("ANYBOT_LIVE_MODEL").unwrap_or_else(|_| "husky".into());
|
||||
let own = crate::model::BOT_COMPUTER_NAME.to_string();
|
||||
let _ = std::fs::remove_dir_all("/tmp/anybot-live");
|
||||
let job = Job {
|
||||
req: ChatRequest {
|
||||
kind: ProviderKind::Custom,
|
||||
base_url: base,
|
||||
api_key: key,
|
||||
model,
|
||||
system: "你是 AnyBot。用工具完成使用者的要求,最後用一句中文回答。".into(),
|
||||
history: vec![Message::user("在 /tmp/anybot-live 建立 hello.txt,內容寫 anybot-was-here,然後用 shell 讀回來,告訴我市面檔裡寫了什麼。")],
|
||||
tools: tools::specs(),
|
||||
session: String::new(),
|
||||
},
|
||||
computers: vec![tools::Target { name: own.clone(), place: tools::Place::Local { workdir: "/tmp".into() } }],
|
||||
default_computer: own.clone(),
|
||||
roles: tools::Roles { own, person: None, server: true },
|
||||
local_execution: false,
|
||||
direct: Arc::new(AtomicBool::new(true)),
|
||||
..test_job()
|
||||
};
|
||||
let (tx, rx) = channel();
|
||||
spawn(job, 1, tx, Arc::new(AtomicBool::new(false)), eframe::egui::Context::default());
|
||||
let mut tools_seen = vec![];
|
||||
let mut answer = String::new();
|
||||
loop {
|
||||
match rx.recv_timeout(Duration::from_secs(180)).expect("loop stalled") {
|
||||
(_, StreamEvent::ToolCall(m)) => tools_seen.push(m.name.clone()),
|
||||
(_, StreamEvent::ToolResult(m)) => {
|
||||
println!("[tool] {}: {}", m.tool_name, m.text.chars().take(120).collect::<String>());
|
||||
tools_seen.push(format!("done:{}", m.tool_name));
|
||||
}
|
||||
(_, StreamEvent::Text(t)) => answer.push_str(&t),
|
||||
(_, StreamEvent::Done) => break,
|
||||
(_, StreamEvent::Error(e)) => panic!("model error: {e}"),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
println!("tools: {tools_seen:?}\nanswer: {answer}");
|
||||
assert!(tools_seen.iter().any(|t| t.contains("shell")), "the model never ran a shell tool: {tools_seen:?}");
|
||||
assert!(answer.contains("anybot-was-here") || std::fs::read_to_string("/tmp/anybot-live/hello.txt").unwrap_or_default().contains("anybot-was-here"), "the file never appeared; answer was: {answer}");
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
fn a_brain_without_chrome_browses_on_its_box() {
|
||||
let own = crate::model::BOT_COMPUTER_NAME;
|
||||
|
|
|
|||
Loading…
Reference in New Issue