use criterion::{Criterion, criterion_group, criterion_main};
use molo::message::Message;
use molo::provider::{FakeProvider, FakeReply};
use molo::tool::{SharedState, ToolRegistry};
use molo::{Agent, Memory, ReActAgent, Tool, ToolError, ToolSchema, WindowMemory};
fn rt() -> tokio::runtime::Runtime {
tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap()
}
fn bench_agent_run(c: &mut Criterion) {
let runtime = rt();
let mut group = c.benchmark_group("agent_run");
group.bench_function("5_rounds", |b| {
b.iter(|| {
runtime.block_on(async {
let provider = FakeProvider::new(vec![FakeReply::Text("hi".into()); 5]);
let mut agent = ReActAgent::new(provider, ToolRegistry::new(), "");
for _ in 0..5 {
agent.run("hi").await.unwrap();
}
})
})
});
group.bench_function("stream_20_rounds", |b| {
b.iter(|| {
runtime.block_on(async {
let provider = FakeProvider::new(vec![FakeReply::Text("hi".into()); 20]);
let mut agent = ReActAgent::new(provider, ToolRegistry::new(), "");
let mut stream = agent.run_stream("hi").await.unwrap();
while let Some(Ok(_)) = futures::StreamExt::next(&mut stream).await {}
})
})
});
group.finish();
}
fn bench_tool_call(c: &mut Criterion) {
struct Noop;
#[molo::async_trait]
impl Tool for Noop {
fn schema(&self) -> ToolSchema {
ToolSchema {
name: "noop".into(),
description: "noop".into(),
parameters: serde_json::json!({}),
}
}
async fn call(
&self,
_arguments: serde_json::Value,
_state: &SharedState,
) -> Result<String, ToolError> {
Ok("ok".into())
}
}
let runtime = rt();
let mut group = c.benchmark_group("tool_call");
group.bench_function("registry_call", |b| {
b.iter(|| {
runtime.block_on(async {
let mut registry = ToolRegistry::new();
registry.register(Noop);
let state = SharedState::new();
registry.call("noop", "{}", &state).await.unwrap();
})
})
});
group.finish();
}
fn bench_window_memory(c: &mut Criterion) {
let runtime = rt();
let mut group = c.benchmark_group("window_memory");
group.bench_function("trim_50_rounds", |b| {
b.iter(|| {
runtime.block_on(async {
let mut memory = WindowMemory::new(200);
for i in 0..50 {
memory
.record(Message::user(format!("user message number {i}")))
.await
.unwrap();
memory
.record(Message::assistant(format!("assistant reply number {i}")))
.await
.unwrap();
}
let _ = memory.context().await.unwrap();
})
})
});
group.finish();
}
criterion_group!(
benches,
bench_agent_run,
bench_tool_call,
bench_window_memory
);
criterion_main!(benches);