metrale_bench/benchmarks/agentic/
trace.rs1use std::io::Write;
17use std::path::{Path, PathBuf};
18
19use crate::http::ChatOutcome;
20
21pub struct Trace {
22 path: Option<PathBuf>,
23}
24
25impl Trace {
26 pub fn start(sandbox: &Path, prompt: &str) -> Self {
29 let path = path_for(sandbox);
30 let trace = Self { path: Some(path) };
31 match std::fs::write(trace.path.as_ref().expect("just set"), header(prompt)) {
32 Ok(()) => trace,
33 Err(e) => {
34 tracing::warn!("agentic: trajectory trace disabled: {e}");
35 Self { path: None }
36 }
37 }
38 }
39
40 pub fn turn(&self, index: usize, outcome: &ChatOutcome) {
43 let mut s = format!("\n── turn {} ───────────────────────────────\n", index + 1);
44 section(&mut s, "reasoning", &outcome.reasoning);
45 section(&mut s, "text", &outcome.text);
46 for call in &outcome.tool_calls {
47 s.push_str(&format!(
48 "[call {}] {} {}\n",
49 call.id, call.name, call.arguments
50 ));
51 }
52 if let Some(reason) = &outcome.finish_reason {
53 s.push_str(&format!("[finish] {reason}\n"));
54 }
55 self.append(&s);
56 }
57
58 pub fn result(&self, tool: &str, content: &str) {
62 let mut s = format!("[result {tool}]\n");
63 s.push_str(content.trim_end());
64 s.push('\n');
65 self.append(&s);
66 }
67
68 fn append(&self, text: &str) {
69 let Some(path) = &self.path else { return };
70 let written = std::fs::OpenOptions::new()
71 .append(true)
72 .open(path)
73 .and_then(|mut f| f.write_all(text.as_bytes()));
74 if let Err(e) = written {
75 tracing::warn!("agentic: could not extend {}: {e}", path.display());
76 }
77 }
78}
79
80fn path_for(sandbox: &Path) -> PathBuf {
81 let mut name = sandbox.file_name().unwrap_or_default().to_os_string();
82 name.push(".trajectory.txt");
83 sandbox.with_file_name(name)
84}
85
86fn header(prompt: &str) -> String {
87 format!("[prompt]\n{}\n", prompt.trim_end())
88}
89
90fn section(out: &mut String, name: &str, body: &str) {
91 if body.trim().is_empty() {
92 return;
93 }
94 out.push_str(&format!("[{name}]\n{}\n", body.trim_end()));
95}
96
97#[cfg(test)]
98#[path = "trace_tests.rs"]
99mod tests;