use std::io;
pub const WORKER_STACK_SIZE: usize = 16 * 1024 * 1024;
pub fn build() -> io::Result<tokio::runtime::Runtime> {
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.thread_stack_size(WORKER_STACK_SIZE)
.build()
}
#[cfg(test)]
mod tests {
use super::*;
const PROVEN_MINIMUM: usize = 8 * 1024 * 1024;
#[test]
fn worker_stack_covers_the_depth_the_agent_future_needs() {
const {
assert!(
WORKER_STACK_SIZE >= PROVEN_MINIMUM,
"worker stack must cover the depth the agent future is proven to need (#2080)"
)
};
}
#[test]
fn the_binary_builds_its_runtime_through_this_builder() {
let main_rs = include_str!("main.rs");
let on_tokio_main_macro = main_rs
.lines()
.any(|line| line.trim().starts_with("#[tokio::main"));
assert!(
!on_tokio_main_macro,
"src/main.rs is back on #[tokio::main], which spawns workers at the 2 MiB default and aborts the first agent turn (#2080)"
);
assert!(
main_rs.contains("runtime::build()"),
"src/main.rs no longer builds its runtime through runtime::build(), so the worker stack is unset (#2080)"
);
}
#[test]
fn an_agent_turn_completes_on_the_production_runtime() {
let rt = build().expect("build the production runtime");
rt.block_on(async {
use crate::brain::agent::service::AgentService;
use crate::db::Database;
use crate::services::{ServiceContext, SessionService};
use crate::tests::agent_service_mocks::MockProvider;
use std::sync::Arc;
let db = Database::connect_in_memory().await.unwrap();
db.run_migrations().await.unwrap();
let context = ServiceContext::new(db.pool().clone());
let agent = AgentService::new_for_test(Arc::new(MockProvider), context.clone()).await;
let sessions = SessionService::new(context);
let session = sessions
.create_session(Some("Runtime smoke".to_string()))
.await
.unwrap();
let reply = agent
.send_message(session.id, "hello".to_string(), None)
.await
.unwrap();
assert!(
!reply.content.is_empty(),
"the production runtime must carry a turn to completion"
);
});
}
}