use std::sync::Arc;
use agent_engine::{EngineHost, HostOpts, Tool, ToolContext, ToolRegistry};
use serde_json::{json, Value};
struct ExtTool;
#[async_trait::async_trait]
impl Tool for ExtTool {
fn name(&self) -> &str {
"alpha:do_thing"
}
fn description(&self) -> &str {
"ext"
}
fn parameters(&self) -> Value {
json!({"type": "object"})
}
async fn execute(&self, _p: Value, _c: ToolContext) -> agent_engine::Result<String> {
Ok("ok".into())
}
fn extension_id(&self) -> Option<&str> {
Some("alpha")
}
}
async fn host_with_disclosure_on() -> Arc<EngineHost> {
static INIT: tokio::sync::OnceCell<()> = tokio::sync::OnceCell::const_new();
INIT.get_or_init(|| async {
let home = std::env::temp_dir().join(format!("synaps-worker-iso-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&home);
std::fs::create_dir_all(&home).unwrap();
std::fs::write(home.join("config"), "progressive_tool_disclosure = true\n").unwrap();
agent_engine::config::set_base_dir_for_tests(home);
let h = EngineHost::boot(HostOpts {
profile: None,
no_extensions: true,
})
.await
.expect("host boot");
h.parts().tools.write().await.register(Arc::new(ExtTool));
assert!(EngineHost::install(h).is_ok(), "first install");
})
.await;
EngineHost::current().expect("installed")
}
#[tokio::test]
async fn worker_ignores_host_progressive_disclosure_and_keeps_extension_tools() {
let h = host_with_disclosure_on().await;
assert!(h.parts().progressive_tool_disclosure, "host has the flag on");
let fg = h.foreground_runtime().await.unwrap();
assert!(fg.progressive_tool_disclosure(), "foreground follows config");
let w = h.worker_runtime().await.unwrap();
assert!(
!w.progressive_tool_disclosure(),
"worker must be `Runtime::new()`'s value: disclosure off"
);
let core = ToolRegistry::without_subagent().tools_schema().len();
let reg = w.tools_shared();
let reg = reg.read().await;
let schema = reg.tools_schema();
assert!(
schema.len() > core,
"worker schema {} must exceed builtin-only {}",
schema.len(),
core
);
assert!(reg.get("alpha:do_thing").is_some(), "extension tool present");
}
#[tokio::test]
async fn worker_has_its_own_http_client_pool() {
let h = host_with_disclosure_on().await;
let fg = h.foreground_runtime().await.unwrap();
let w1 = h.worker_runtime().await.unwrap();
let w2 = h.worker_runtime().await.unwrap();
let fg_id = fg.http_client_pool_id();
assert_ne!(fg_id, w1.http_client_pool_id(), "worker pool != host pool");
assert_ne!(fg_id, w2.http_client_pool_id(), "worker pool != host pool");
assert_ne!(
w1.http_client_pool_id(),
w2.http_client_pool_id(),
"each worker owns its pool"
);
let fg2 = h.foreground_runtime().await.unwrap();
assert_eq!(fg_id, fg2.http_client_pool_id());
}