use std::path::Path;
use crate::AppModel;
use crate::boundary::Action;
use crate::cli_outbound::Cli;
use crate::fork::{self, Choices};
use crate::rail::Pin;
use super::super::InspectorState;
pub struct Seat {
pub ws: std::path::PathBuf,
pub agent_id: String,
pub pin: Option<Pin>,
}
pub fn seat(
ui: &mut egui::Ui,
model: &mut AppModel,
inspector: &mut InspectorState,
at: &Seat,
lernie: &Cli,
bl: &Cli,
) {
let (ws, agent_id, pin) = (at.ws.as_path(), at.agent_id.as_str(), at.pin.as_ref());
let Some(pin) = pin else {
inspector.fork = None;
return;
};
let choices = choices(model, inspector, ws, pin);
if !choices.fireable() {
inspector.fork = None;
return;
}
let composer = inspector
.fork
.get_or_insert_with(|| fork::composer::Composer::seeded(&choices));
if !fork::render::render(ui, composer, &choices) {
return;
}
let attempts = composer.attempts.clone();
let goal = composer.goal.clone();
inspector.fork = None;
fire(model, ws, agent_id, &goal, &attempts, lernie, bl);
}
fn choices(model: &AppModel, inspector: &mut InspectorState, ws: &Path, pin: &Pin) -> Choices {
let snap = std::sync::Arc::clone(model.derivation());
let key = (ws.to_path_buf(), pin.commit.clone());
let root = fork::skills_root(model.yog_data_root());
inspector
.fork_memo
.read(&snap, key, &mut || fork::choices(ws, &pin.commit, &root))
.clone()
}
fn fire(
model: &mut AppModel,
ws: &Path,
agent_id: &str,
goal: &str,
attempts: &[fork::Attempt],
lernie: &Cli,
bl: &Cli,
) {
let deps = model.boundary_deps(lernie, bl);
let ts = super::super::now_ts();
for attempt in attempts {
let action = Action::Fork {
workspace: ws.to_path_buf(),
parent: agent_id.to_owned(),
attempt: attempt.clone(),
goal: goal.to_owned(),
};
let _ = model.dispatch(&deps, &ts, &action);
}
model.after_lernie_verb();
}