loopd: write the next epoch from a compaction summary
Co-Authored-By: ornith-1.5-35b-a3b <agent@wntrmute.dev>
This commit is contained in:
@@ -2,12 +2,14 @@
|
||||
//! (M5d spec, section 3). Task 07 writes the next files; task 08 calls this after a turn.
|
||||
|
||||
use bxcore::sanitize::neutralise;
|
||||
use bxcore::{LogRecord, Usage};
|
||||
use bxcore::{Epoch, LogRecord, Timestamp, Usage};
|
||||
|
||||
use crate::baseline::messages_with_carry;
|
||||
use crate::baseline::{Baseline, messages_with_carry};
|
||||
use crate::config::Config;
|
||||
use crate::llama::{ChatMessage, ChatRequest, Client};
|
||||
use crate::memory::MemorySource;
|
||||
use crate::session::Session;
|
||||
use crate::tools::Registry;
|
||||
use crate::turn::is_context_full;
|
||||
|
||||
/// Why a summary call or a next-epoch write failed. Every variant's `Display` ends with the
|
||||
@@ -90,3 +92,44 @@ pub fn summarise(cfg: &Config, client: &Client, session: &Session) -> Result<Str
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
/// Append `EpochEnd` (unless it is already last), rebuild the baseline from `memory`, and
|
||||
/// switch `session` onto the next epoch. When the current log already ends with `EpochEnd`,
|
||||
/// that record's summary is the carry and the argument is ignored.
|
||||
pub fn commit(
|
||||
session: &mut Session,
|
||||
cfg: &Config,
|
||||
registry: &Registry,
|
||||
memory: &dyn MemorySource,
|
||||
summary: String,
|
||||
) -> Result<(), CompactError> {
|
||||
let (next, summary) = match session.records().last() {
|
||||
Some(LogRecord::EpochEnd { next, summary, .. }) => (*next, summary.clone()),
|
||||
_ => {
|
||||
let next = Epoch(session.epoch().0.saturating_add(1));
|
||||
session
|
||||
.append(LogRecord::EpochEnd {
|
||||
time: Timestamp::now(),
|
||||
next,
|
||||
summary: summary.clone(),
|
||||
})
|
||||
.map_err(|e| CompactError::Failed {
|
||||
detail: e.to_string(),
|
||||
})?;
|
||||
(next, summary)
|
||||
}
|
||||
};
|
||||
let block = memory
|
||||
.block()
|
||||
.map_err(|e| CompactError::Failed { detail: e })?;
|
||||
let baseline =
|
||||
Baseline::assemble_with(cfg, registry, &block).map_err(|e| CompactError::Failed {
|
||||
detail: e.to_string(),
|
||||
})?;
|
||||
session
|
||||
.begin_epoch(next, baseline, summary)
|
||||
.map_err(|e| CompactError::Failed {
|
||||
detail: e.to_string(),
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -261,6 +261,43 @@ impl Session {
|
||||
fn log_path(&self) -> PathBuf {
|
||||
self.dir.join(format!("{}.jsonl", self.epoch.0))
|
||||
}
|
||||
|
||||
/// Write `<n>.baseline.json` and `<n>.jsonl` with `SessionStart`, and switch this session
|
||||
/// onto that epoch. The live slot and `next_call` stay. Callers pass the carry that
|
||||
/// `messages_with_carry` will insert.
|
||||
pub(crate) fn begin_epoch(
|
||||
&mut self,
|
||||
next: Epoch,
|
||||
baseline: Baseline,
|
||||
carry: String,
|
||||
) -> Result<(), SessionError> {
|
||||
let n = next.0;
|
||||
let baseline_path = self.dir.join(format!("{n}.baseline.json"));
|
||||
let json = baseline.to_json().map_err(SessionError::Encode)?;
|
||||
std::fs::write(&baseline_path, json)
|
||||
.map_err(|e| SessionError::Io(baseline_path.clone(), e))?;
|
||||
let log_path = self.dir.join(format!("{n}.jsonl"));
|
||||
let log = OpenOptions::new()
|
||||
.create_new(true)
|
||||
.append(true)
|
||||
.open(&log_path)
|
||||
.map_err(|e| SessionError::Io(log_path.clone(), e))?;
|
||||
self.prior_users = self.prior_users.saturating_add(count_users(&self.records));
|
||||
self.prior_untrusted = self.prior_untrusted || any_untrusted(&self.records);
|
||||
self.epoch = next;
|
||||
self.baseline = baseline;
|
||||
self.carry = Some(carry);
|
||||
self.records = Vec::new();
|
||||
self.log = log;
|
||||
let hash = self.baseline.hash().map_err(SessionError::Baseline)?;
|
||||
self.persist(LogRecord::SessionStart {
|
||||
time: Timestamp::now(),
|
||||
session: self.id.clone(),
|
||||
epoch: next,
|
||||
slot: self.slot,
|
||||
baseline: hash,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Epoch numbers that have both `<n>.jsonl` and `<n>.baseline.json`, sorted.
|
||||
|
||||
Reference in New Issue
Block a user