#![allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::panic,
clippy::indexing_slicing,
reason = "test code"
)]
use super::super::*;
use crate::prefix::{FrozenPrefix, FrozenSegment, SegmentSlot};
use kernel::ledger::chain_hash;
use kernel::{EventDraft, GENESIS_PREV};
pub(super) struct TestLedger {
pub(super) lines: Vec<Vec<u8>>,
next: kernel::Seq,
prev: B3Hash,
}
impl TestLedger {
pub(super) fn new() -> Self {
TestLedger {
lines: Vec::new(),
next: kernel::Seq::FIRST,
prev: GENESIS_PREV,
}
}
pub(super) fn kinds(&self) -> Vec<String> {
self.lines
.iter()
.map(|line| {
let value: serde_json::Value = serde_json::from_slice(line).unwrap();
value["kind"].as_str().unwrap().to_owned()
})
.collect()
}
}
impl Ledger for TestLedger {
fn append(&mut self, draft: EventDraft) -> Result<EventRef, AxError> {
let record = kernel::EventRecord::from_draft(draft, self.next, self.prev);
let line = record.canonical_line()?;
self.prev = chain_hash(&line);
self.next = self.next.next()?;
let echo = record.to_ref();
self.lines.push(line);
Ok(echo)
}
}
pub(super) struct OneShotModel {
pub(super) calls: Vec<ToolCall>,
}
impl Model for OneShotModel {
fn call(&mut self, _req: &ModelRequest) -> Result<ModelReturn, AxError> {
Ok(ModelReturn::bare(
kernel::model::message_payload(&[ContentBlock::Text {
text: "thinking".to_owned(),
}])
.unwrap(),
std::mem::take(&mut self.calls),
))
}
}
pub(super) fn prefix() -> FrozenPrefix {
FrozenPrefix::assemble(
FrozenSegment::new(SegmentSlot::City, b"c".to_vec()),
FrozenSegment::new(SegmentSlot::Building, b"b".to_vec()),
FrozenSegment::new(SegmentSlot::Resident, b"r".to_vec()),
FrozenSegment::new(SegmentSlot::Run, b"j".to_vec()),
)
.unwrap()
}
pub(super) fn blank_conversation() -> &'static Conversation {
Box::leak(Box::new(Conversation::new()))
}
pub(super) fn stopped(at: u64) -> impl FnMut() -> Result<TimeMs, AxError> {
move || Ok(TimeMs::new(at))
}
pub(super) fn opened<const AT: u64>() -> Turn<'static, Assembling> {
let now: &'static mut dyn FnMut() -> Result<TimeMs, AxError> =
Box::leak(Box::new(|| -> Result<TimeMs, AxError> {
Ok(TimeMs::new(AT))
}));
Turn::begin(run_id(), "resident@sim.1".into(), TimeMs::new(AT), now)
}
pub(super) fn run_id() -> RunId {
RunId::parse("0198f6a2-7c4a-7bbb-9d1e-00000000000a").unwrap()
}
pub(super) fn shape() -> CallShape {
CallShape {
model: "script".to_owned(),
max_tokens: kernel::Ceiling::new(512),
effort: None,
context_tokens: 0,
}
}
pub(super) fn advance<N>(outcome: PhaseOutcome<N>) -> N {
match outcome {
PhaseOutcome::Advanced(next) => next,
PhaseOutcome::Cancelled(_) => panic!("expected the phase to advance"),
}
}
pub(super) fn probe_call() -> ToolCall {
ToolCall {
id: "call-1".to_owned(),
name: kernel::ToolName::parse("probe").unwrap(),
args: Payload::empty(),
}
}