use anyhow::{Context, Result, bail};
use rlx_llama_base::LlamaBaseConfig;
use std::path::{Path, PathBuf};
pub use rlx_llama32::{Llama32ConfigSource, Llama32Runner, Llama32RunnerBuilder};
pub const PLAN_MILESTONE: &str = "M4";
pub const FAMILY: &str = "Bonsai";
pub struct BonsaiRunner {
inner: Llama32Runner,
config: LlamaBaseConfig,
}
impl BonsaiRunner {
pub fn builder() -> BonsaiRunnerBuilder {
BonsaiRunnerBuilder::default()
}
pub fn config(&self) -> &LlamaBaseConfig {
&self.config
}
pub fn inner(&self) -> &Llama32Runner {
&self.inner
}
pub fn inner_mut(&mut self) -> &mut Llama32Runner {
&mut self.inner
}
pub fn generate_packed(
&mut self,
prompt_ids: &[u32],
n_new: usize,
on_token: impl FnMut(u32),
) -> Result<Vec<u32>> {
self.inner.generate_packed(prompt_ids, n_new, on_token)
}
}
#[derive(Debug, Clone, Default)]
pub struct BonsaiRunnerBuilder {
weights: Option<PathBuf>,
inner: Llama32RunnerBuilder,
}
impl BonsaiRunnerBuilder {
pub fn weights(mut self, path: impl Into<PathBuf>) -> Self {
let p: PathBuf = path.into();
self.weights = Some(p.clone());
self.inner = self.inner.weights(p);
self
}
pub fn max_seq(mut self, n: usize) -> Self {
self.inner = self.inner.max_seq(n);
self
}
pub fn packed_weights(mut self, on: bool) -> Self {
self.inner = self.inner.packed_weights(on);
self
}
pub fn build(self) -> Result<BonsaiRunner> {
let weights = self
.weights
.as_ref()
.ok_or_else(|| anyhow::anyhow!("weights path required (call .weights(...))"))?
.clone();
let config = LlamaBaseConfig::from_gguf_path(&weights)
.with_context(|| format!("rlx-bonsai: parse {weights:?}"))?;
if config.arch != "llama" {
bail!(
"rlx-bonsai: expected `general.architecture = llama` (Bonsai's GGUF tag); \
got `{}` at {weights:?}",
config.arch
);
}
let inner = self
.inner
.build()
.context("rlx-bonsai: building underlying Llama32Runner")?;
Ok(BonsaiRunner { inner, config })
}
}
pub fn cli_run(args: &[String]) -> Result<()> {
if let Some(first) = args.iter().position(|a| a == "--weights") {
if let Some(path) = args.get(first + 1) {
let cfg = LlamaBaseConfig::from_gguf_path(Path::new(path))
.with_context(|| format!("rlx-bonsai: parse {path}"))?;
if cfg.arch != "llama" {
bail!(
"rlx-bonsai: {path}: GGUF arch = `{}`, expected `llama` (Bonsai)",
cfg.arch
);
}
}
}
rlx_llama32::cli::run(args)
}