Add --ledger-file arg for explicit ledger path control
Defaults to <output_dir>/run_ledger.jsonl as before. Pass --ledger-file to read from (and write to) a specific ledger, enabling multiple ledger files to seed different search campaigns or merge results from separate runs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
17
src/agent.rs
17
src/agent.rs
@@ -205,8 +205,12 @@ pub async fn run(cli: &Cli) -> Result<()> {
|
|||||||
let system = prompts::system_prompt(schema, claude.family());
|
let system = prompts::system_prompt(schema, claude.family());
|
||||||
info!("model family: {}", claude.family().name());
|
info!("model family: {}", claude.family().name());
|
||||||
|
|
||||||
|
// Resolve ledger path: explicit --ledger-file takes precedence, else <output_dir>/run_ledger.jsonl
|
||||||
|
let ledger_path = cli.ledger_file.clone().unwrap_or_else(|| cli.output_dir.join("run_ledger.jsonl"));
|
||||||
|
info!("ledger: {}", ledger_path.display());
|
||||||
|
|
||||||
// Load prior runs from ledger and build cross-run context for iteration 1
|
// Load prior runs from ledger and build cross-run context for iteration 1
|
||||||
let prior_summary = load_prior_summary(&cli.output_dir, &swym).await;
|
let prior_summary = load_prior_summary(&ledger_path, &swym).await;
|
||||||
|
|
||||||
// Agent state
|
// Agent state
|
||||||
let mut history: Vec<IterationRecord> = Vec::new();
|
let mut history: Vec<IterationRecord> = Vec::new();
|
||||||
@@ -412,7 +416,7 @@ pub async fn run(cli: &Cli) -> Result<()> {
|
|||||||
info!(" condition audit: {}", serde_json::to_string_pretty(audit).unwrap_or_default());
|
info!(" condition audit: {}", serde_json::to_string_pretty(audit).unwrap_or_default());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
append_ledger_entry(&cli.output_dir, &result, &strategy);
|
append_ledger_entry(&ledger_path, &result, &strategy);
|
||||||
results.push(result);
|
results.push(result);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -599,7 +603,7 @@ async fn run_single_backtest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Append a ledger entry for a completed backtest so future runs can learn from it.
|
/// Append a ledger entry for a completed backtest so future runs can learn from it.
|
||||||
fn append_ledger_entry(output_dir: &Path, result: &BacktestResult, strategy: &Value) {
|
fn append_ledger_entry(ledger: &Path, result: &BacktestResult, strategy: &Value) {
|
||||||
// Skip nil run_ids (error placeholders)
|
// Skip nil run_ids (error placeholders)
|
||||||
if result.run_id == Uuid::nil() {
|
if result.run_id == Uuid::nil() {
|
||||||
return;
|
return;
|
||||||
@@ -620,11 +624,10 @@ fn append_ledger_entry(output_dir: &Path, result: &BacktestResult, strategy: &Va
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let path = output_dir.join("run_ledger.jsonl");
|
|
||||||
if let Err(e) = std::fs::OpenOptions::new()
|
if let Err(e) = std::fs::OpenOptions::new()
|
||||||
.append(true)
|
.append(true)
|
||||||
.create(true)
|
.create(true)
|
||||||
.open(&path)
|
.open(ledger)
|
||||||
.and_then(|mut f| writeln!(f, "{}", line))
|
.and_then(|mut f| writeln!(f, "{}", line))
|
||||||
{
|
{
|
||||||
warn!("could not write ledger entry: {e}");
|
warn!("could not write ledger entry: {e}");
|
||||||
@@ -634,8 +637,8 @@ fn append_ledger_entry(output_dir: &Path, result: &BacktestResult, strategy: &Va
|
|||||||
/// Load the run ledger, fetch metrics via the compare endpoint, and return a compact
|
/// Load the run ledger, fetch metrics via the compare endpoint, and return a compact
|
||||||
/// prior-results summary string for the initial prompt. Returns `None` if the ledger
|
/// prior-results summary string for the initial prompt. Returns `None` if the ledger
|
||||||
/// is absent, empty, or the compare call fails.
|
/// is absent, empty, or the compare call fails.
|
||||||
async fn load_prior_summary(output_dir: &Path, swym: &SwymClient) -> Option<String> {
|
async fn load_prior_summary(ledger: &Path, swym: &SwymClient) -> Option<String> {
|
||||||
let path = output_dir.join("run_ledger.jsonl");
|
let path = ledger;
|
||||||
let contents = std::fs::read_to_string(&path).ok()?;
|
let contents = std::fs::read_to_string(&path).ok()?;
|
||||||
|
|
||||||
// Parse all ledger entries
|
// Parse all ledger entries
|
||||||
|
|||||||
@@ -118,6 +118,13 @@ pub struct Cli {
|
|||||||
#[arg(long, default_value = "./results")]
|
#[arg(long, default_value = "./results")]
|
||||||
pub output_dir: PathBuf,
|
pub output_dir: PathBuf,
|
||||||
|
|
||||||
|
/// Path to the run ledger JSONL file used for cross-run learning.
|
||||||
|
/// Defaults to <output_dir>/run_ledger.jsonl when not specified.
|
||||||
|
/// Pass a different path to seed a new run from a specific ledger
|
||||||
|
/// (e.g. a curated export from a previous campaign).
|
||||||
|
#[arg(long)]
|
||||||
|
pub ledger_file: Option<PathBuf>,
|
||||||
|
|
||||||
/// Poll interval in seconds when waiting for backtest completion.
|
/// Poll interval in seconds when waiting for backtest completion.
|
||||||
#[arg(long, default_value_t = 2)]
|
#[arg(long, default_value_t = 2)]
|
||||||
pub poll_interval_secs: u64,
|
pub poll_interval_secs: u64,
|
||||||
|
|||||||
Reference in New Issue
Block a user