use std::{env, path::PathBuf};
use basis::{
AllowAll, Event, FnSink, MemoryConfig, ModelSelector, Workspace, WorkspaceMemoryRoot,
memory::{MemoryKind, file_contents},
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut args = env::args().skip(1);
let path = args.next().unwrap_or_else(|| ".".to_string());
let prompt = args
.next()
.unwrap_or_else(|| "Summarize this repository in detail.".to_string());
let memory_root = PathBuf::from(args.next().unwrap_or_else(|| "./memories".to_string()));
let mut builder = Workspace::builder(&path).with_memory(MemoryConfig {
global_root: None,
workspace_root: WorkspaceMemoryRoot::Dir(memory_root.clone()),
});
if let Ok(model) = env::var("BASIS_MODEL") {
builder = builder.with_model(ModelSelector::Id(model));
}
let workspace = builder.open().await?;
for memory in workspace.memories() {
println!("remembered: {} — {}", memory.name, memory.description);
}
let root = memory_root.clone();
let mut filed = 0_usize;
let report = workspace
.prepare(prompt)?
.execute_with_approver(
FnSink::new(move |event| {
if let Event::CompactionCompleted {
replaced_items,
preserved_items,
extracted_facts,
summary_preview,
..
} = event
{
filed += 1;
let body = format!(
"{replaced_items} earlier items were replaced by a summary \
({preserved_items} kept, {extracted_facts} facts extracted).\n\n\
Summary preview:\n\n{summary_preview}",
);
std::fs::create_dir_all(&root)?;
std::fs::write(
root.join(format!("compaction-{filed}.md")),
file_contents(
&format!("compaction-{filed}"),
"what a summarizing pass replaced, kept for the next session",
MemoryKind::Reference,
&body,
),
)?;
eprintln!("filed compaction-{filed}.md");
}
Ok(())
}),
AllowAll,
)
.await?;
println!(
"{}",
report.final_message.as_deref().unwrap_or("(no message)")
);
Ok(())
}