use salamander::agent::EventBody;
use salamander::{AgentDb, Change, Event, IndexedView};
fn main() -> salamander::Result<()> {
let dir = fresh_dir("query_views");
let mut db = AgentDb::open(&dir)?;
let view = IndexedView::builder()
.project(|e: &Event<EventBody>| match &e.body {
EventBody::ToolCall { call_id, tool, .. } => {
Some(Change::put(call_id.clone(), tool.clone()))
}
_ => None, })
.index("by_tool", |tool: &String| vec![tool.as_bytes().to_vec()])
.build();
db.register("tools", Box::new(view))?;
for (id, tool) in [
("t1", "grep"),
("t2", "git_blame"),
("t3", "grep"),
("t4", "open_pr"),
] {
db.append("s", tool_call(id, tool))?;
}
let tools = db
.view::<IndexedView<String, String, EventBody>>("tools")
.unwrap();
println!("get(\"t2\") = {:?}", tools.get("t2"));
let range: Vec<_> = tools.range("t1".to_string().."t3".to_string()).collect();
println!("range(t1..t3) = {range:?}");
println!("prefix(\"t\") = {} rows", tools.prefix("t").count());
println!("by(by_tool, grep) = {:?}", tools.by("by_tool", b"grep"));
Ok(())
}
fn tool_call(id: &str, tool: &str) -> EventBody {
EventBody::ToolCall {
call_id: id.into(),
tool: tool.into(),
args_json: "{}".into(),
}
}
fn fresh_dir(name: &str) -> std::path::PathBuf {
let dir = std::env::temp_dir().join(format!("salamander-example-{name}"));
let _ = std::fs::remove_dir_all(&dir);
dir
}