use std::borrow::Cow;
use std::collections::BTreeMap;
use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};
use std::thread;
use super::*;
fn read_http_request(stream: &mut TcpStream) -> String {
let mut bytes = Vec::new();
let mut buffer = [0_u8; 4096];
let mut header_end = None;
let mut content_length = 0_usize;
loop {
let read = stream.read(&mut buffer).expect("read request");
if read == 0 {
break;
}
bytes.extend_from_slice(&buffer[..read]);
if header_end.is_none()
&& let Some(index) = bytes.windows(4).position(|window| window == b"\r\n\r\n")
{
let end = index + 4;
header_end = Some(end);
let headers = String::from_utf8_lossy(&bytes[..end]);
content_length = headers
.lines()
.find_map(|line| {
let (name, value) = line.split_once(':')?;
name.eq_ignore_ascii_case("content-length")
.then(|| value.trim().parse::<usize>().expect("content length"))
})
.unwrap_or_default();
}
if header_end.is_some_and(|end| bytes.len() >= end + content_length) {
break;
}
}
String::from_utf8(bytes).expect("request should be utf8")
}
fn spawn_two_response_server() -> (String, thread::JoinHandle<Vec<String>>) {
let listener = TcpListener::bind("127.0.0.1:0").expect("bind test server");
let address = listener.local_addr().expect("read server address");
let handle = thread::spawn(move || {
let mut requests = Vec::new();
for index in 1..=2 {
let (mut stream, _) = listener.accept().expect("accept request");
requests.push(read_http_request(&mut stream));
let response_id = format!("resp_{index}");
let body = format!(
concat!(
"data: {{\"type\":\"response.created\",\"response\":{{\"id\":\"{}\",\"model\":\"gpt-5\",\"status\":\"in_progress\"}}}}\n\n",
"data: {{\"type\":\"response.completed\",\"response\":{{\"id\":\"{}\",\"model\":\"gpt-5\",\"status\":\"completed\"}}}}\n\n"
),
response_id, response_id
);
let response = format!(
concat!(
"HTTP/1.1 200 OK\r\n",
"connection: close\r\n",
"content-type: text/event-stream\r\n",
"content-length: {}\r\n\r\n",
"{}"
),
body.len(),
body
);
stream
.write_all(response.as_bytes())
.expect("write response");
}
requests
});
(format!("http://{address}/"), handle)
}
#[tokio::test]
async fn compatible_provider_skips_automatic_previous_response_id_chaining() {
let (base_url, handle) = spawn_two_response_server();
let provider = compatible_provider(&base_url, "test-key");
for (index, message) in ["first", "second"].into_iter().enumerate() {
let request = mentra::provider_core::Request {
model: Cow::Borrowed("gpt-5"),
system: None,
messages: Cow::Owned(vec![mentra::Message::user(mentra::ContentBlock::text(
message,
))]),
tools: Cow::Owned(Vec::new()),
tool_choice: None,
temperature: None,
max_output_tokens: None,
metadata: Cow::Owned(BTreeMap::new()),
provider_request_options: Default::default(),
};
let mut stream = provider
.session()
.stream_response(request)
.await
.expect("compatible provider should stream");
while let Some(event) = stream.recv().await {
event.expect("response event should decode");
}
if index == 0 {
assert_eq!(
provider.session().latest_response_id().as_deref(),
Some("resp_1"),
"the second request must have provider state available to suppress"
);
}
}
let requests = handle.join().expect("server should capture requests");
for request in requests {
let body = request.split("\r\n\r\n").nth(1).unwrap_or_default();
let payload: serde_json::Value =
serde_json::from_str(body).expect("request body should be json");
assert!(payload.get("previous_response_id").is_none());
}
}
#[test]
fn builders_return_new_values() {
let base = RuntimeBuilder::default();
let derived = base.with_provider(BuiltinProvider::Anthropic);
assert_eq!(derived.provider, Some(BuiltinProvider::Anthropic));
assert_eq!(
RuntimeBuilder::default().provider,
None,
"a fresh builder detects the provider"
);
}
#[test]
fn history_goes_where_mentra_puts_it_unless_the_caller_says_otherwise() {
assert_eq!(RuntimeBuilder::default().history, None);
assert_eq!(
RuntimeBuilder::default()
.with_store_dir("/elsewhere")
.history,
Some(History::Directory(PathBuf::from("/elsewhere")))
);
assert_eq!(
RuntimeBuilder::default().with_ephemeral_history().history,
Some(History::Ephemeral)
);
}
#[test]
fn the_last_word_about_history_is_the_one_that_counts() {
assert_eq!(
RuntimeBuilder::default()
.with_store_dir("/elsewhere")
.with_ephemeral_history()
.history,
Some(History::Ephemeral)
);
assert_eq!(
RuntimeBuilder::default()
.with_ephemeral_history()
.with_store_dir("/elsewhere")
.history,
Some(History::Directory(PathBuf::from("/elsewhere")))
);
}
#[test]
fn a_supplied_credential_is_not_printed() {
let printed = format!(
"{:?}",
RuntimeBuilder::default().with_api_key("sk-secret-value")
);
assert!(!printed.contains("sk-secret-value"));
assert!(printed.contains("redacted"));
}
#[test]
fn command_environment_is_scoped_and_redacted() {
let builder = RuntimeBuilder::default()
.with_command_environment("BASIS_TASK_ID", "parent")
.with_command_environment("BASIS_TASK_ID", "child");
assert_eq!(
builder.command_environment.get("BASIS_TASK_ID"),
Some(&"child".to_string()),
"the last fixed value is the only value a command should receive"
);
let printed = format!("{builder:?}");
assert!(printed.contains("BASIS_TASK_ID"), "{printed}");
assert!(!printed.contains("child"), "{printed}");
}
struct Named(&'static str);
#[async_trait::async_trait]
impl Interceptor for Named {
fn name(&self) -> &str {
self.0
}
async fn intercept(
&self,
_call: &crate::HookRequest,
) -> Result<crate::HookOutcome, crate::InterceptorError> {
Ok(crate::HookOutcome::Allow)
}
}
#[test]
fn interceptors_append_in_the_order_they_were_registered() {
let builder = RuntimeBuilder::default()
.with_interceptor(Named("first"))
.with_interceptor(Named("second"));
assert_eq!(
builder
.interceptors
.iter()
.map(|interceptor| interceptor.name())
.collect::<Vec<_>>(),
vec!["first", "second"]
);
assert!(
RuntimeBuilder::default().interceptors.is_empty(),
"a fresh builder intercepts nothing"
);
}
#[test]
fn a_registered_interceptor_is_named_in_the_debug_view() {
let printed = format!(
"{:?}",
RuntimeBuilder::default().with_interceptor(Named("redact"))
);
assert!(printed.contains("redact"), "{printed}");
}
#[test]
fn the_shared_policy_grants_commands_with_workspace_bounded_patience() {
let printed = format!("{:?}", shared_policy());
assert!(printed.contains("allow_shell_commands: true"), "{printed}");
assert!(
printed.contains("allow_background_commands: true"),
"{printed}"
);
assert!(
printed.contains("default_command_timeout: 120s"),
"{printed}"
);
assert!(printed.contains("max_command_timeout: 600s"), "{printed}");
assert!(
printed.contains("allowed_read_roots: []") && printed.contains("allowed_write_roots: []"),
"no roots: each agent is confined to its own base_dir, and no \
workspace's root may widen another's: {printed}"
);
}
#[test]
fn a_shared_runtime_resolves_its_provider_without_the_network() {
let runtime = RuntimeBuilder::default()
.with_base_url("http://127.0.0.1:1/v1")
.with_api_key("test-key")
.with_ephemeral_history()
.build()
.expect("builds offline");
assert_eq!(runtime.provider(), "openai");
}