98 lines
2.9 KiB
Rust
98 lines
2.9 KiB
Rust
//! A turn-loop setup shared by the `turn` and `limits` tests: a home, a fake server, a scripted
|
|
//! port and a registry. Included with `#[path]` because it needs `loopd::turn`, which the earlier
|
|
//! tasks' tests must not depend on. Do not edit.
|
|
|
|
#![allow(dead_code)]
|
|
|
|
use crate::support::{FakeServer, Home, ScriptedPort};
|
|
use loopd::baseline::Baseline;
|
|
use loopd::llama::Client;
|
|
use loopd::session::Session;
|
|
use loopd::tools::Registry;
|
|
use loopd::turn::{Runtime, TurnError, run_turn};
|
|
use proto::{LogRecord, SessionId, ToolResponse, TurnEvent};
|
|
|
|
pub struct Setup {
|
|
pub home: Home,
|
|
pub server: FakeServer,
|
|
pub cfg: loopd::config::Config,
|
|
pub client: Client,
|
|
pub port: ScriptedPort,
|
|
pub registry: Registry,
|
|
}
|
|
|
|
pub fn setup(replies: Vec<ToolResponse>) -> Setup {
|
|
let home = Home::new();
|
|
let server = FakeServer::start();
|
|
let cfg = home.config(&server.socket);
|
|
let client = Client::new(cfg.clone());
|
|
Setup {
|
|
home,
|
|
server,
|
|
cfg,
|
|
client,
|
|
port: ScriptedPort::new(replies),
|
|
registry: Registry::m2b(),
|
|
}
|
|
}
|
|
|
|
impl Setup {
|
|
pub fn session(&self, id: &str) -> Session {
|
|
let baseline = Baseline::assemble(&self.cfg, &self.registry).unwrap();
|
|
Session::create(
|
|
&self.home.dir,
|
|
SessionId::new(id).unwrap(),
|
|
baseline,
|
|
self.cfg.slots.main,
|
|
)
|
|
.unwrap()
|
|
}
|
|
|
|
pub fn runtime(&self) -> Runtime<'_> {
|
|
Runtime {
|
|
cfg: &self.cfg,
|
|
client: &self.client,
|
|
port: &self.port,
|
|
registry: &self.registry,
|
|
}
|
|
}
|
|
|
|
pub fn turn(
|
|
&self,
|
|
session: &mut Session,
|
|
text: &str,
|
|
) -> (Result<loopd::turn::TurnOutcome, TurnError>, Vec<TurnEvent>) {
|
|
let mut events = Vec::new();
|
|
let result = run_turn(session, &self.runtime(), text, &mut |e| {
|
|
events.push(e.clone())
|
|
});
|
|
(result, events)
|
|
}
|
|
}
|
|
|
|
/// The recordings were made in separate conversations, so their timings do not line up and the
|
|
/// loop rightly reports cache losses between them. Most tests are not about that, so `types`
|
|
/// and `records` leave `CacheLoss` out; one test checks it on purpose.
|
|
pub fn without_cache_loss(records: &[LogRecord]) -> Vec<LogRecord> {
|
|
records
|
|
.iter()
|
|
.filter(|r| !matches!(r, LogRecord::CacheLoss { .. }))
|
|
.cloned()
|
|
.collect()
|
|
}
|
|
|
|
pub fn types(records: &[LogRecord]) -> Vec<&'static str> {
|
|
without_cache_loss(records)
|
|
.iter()
|
|
.map(|r| match r {
|
|
LogRecord::SessionStart { .. } => "start",
|
|
LogRecord::User { .. } => "user",
|
|
LogRecord::Assistant { .. } => "assistant",
|
|
LogRecord::Usage { .. } => "usage",
|
|
LogRecord::ToolResult { .. } => "tool_result",
|
|
LogRecord::CacheLoss { .. } => "cache_loss",
|
|
LogRecord::EpochEnd { .. } => "epoch_end",
|
|
})
|
|
.collect()
|
|
}
|