use crate::actions::verbs;
use crate::model_pick::Pick;
use crate::ui_state::UiState;
use super::reply::Reply;
use super::{Action, config, control, fan, fleet, interrupt, login, monitor, routing};
mod advertise;
mod arms;
mod delete_exec;
mod deps;
mod doors;
mod enroll;
mod resolve;
mod signin;
use arms::{acknowledge, fork, outcome, pin, retarget, spend, staged, wrote};
use delete_exec::{delete_agent, unmake};
pub use deps::{Caller, Deps};
pub use doors::{prepare, prompt};
use resolve::resolve_workspace;
pub(crate) use signin::gate as signin_gate;
pub fn dispatch(deps: &Deps, ui: &mut UiState, ts: &str, action: &Action) -> Result<Reply, String> {
let (bl, root) = (&deps.bl, deps.state_root.as_path());
let ws: &std::path::Path = &match action.workspace() {
Some(name) => resolve_workspace(deps, action, &name)?,
None => std::path::PathBuf::new(),
};
let project: &std::path::Path = &match action.project() {
Some(name) => deps.snapshot.project_path(&name)?,
None => std::path::PathBuf::new(),
};
let agent: &str = &super::address::resolve_agent(&deps.snapshot, ws, action.agent())?;
match action {
Action::Message { content, .. } => {
outcome(verbs::message(&deps.bound(ws), root, ts, agent, content))
}
Action::Stop { .. } => outcome(verbs::stop(&deps.bound(ws), root, ts, agent)),
Action::Interrupt { content, .. } => interrupt::interrupt(deps, ts, ws, agent, content),
Action::Scan { .. } => outcome(verbs::scan(&deps.bound(ws), root, ts)),
Action::Nudge { .. } => control::advance(deps, ts, ws, agent).map(|()| Reply::Nudged),
Action::Retarget { .. } => outcome(retarget(deps, ts, ws, agent)),
Action::Fork { attempt, goal, .. } => fork(deps, ts, ws, agent, attempt, goal),
Action::Ball(verb) => match verb {
verbs::Verb::Close { id, name, .. } => spend(verbs::close, deps, ts, project, id, name),
verbs::Verb::Assign { id, name, .. } => {
spend(verbs::assign, deps, ts, project, id, name)
}
verbs::Verb::Release { id, name, .. } => {
spend(verbs::unclaim, deps, ts, project, id, name)
}
verbs::Verb::Create { name, fields, .. } => {
outcome(verbs::create(bl, root, ts, project, name, fields))
}
verbs::Verb::Update {
id, name, fields, ..
} => outcome(verbs::update(bl, root, ts, project, id, name, fields)),
},
Action::Prepare { payload, .. } => staged(deps, ts, ws, project, payload),
Action::Prompt {
prepared,
goal,
seed,
} => prompt(deps, ui, ts, ws, prepared, goal, *seed)
.map(|conversation| Reply::Started { conversation }),
Action::Fan(verb) => fan::dispatch(deps, ts, verb),
Action::DeleteWorkspace { typed, .. } => unmake(deps, ui, ts, ws, typed),
Action::DeleteAgent { typed, .. } => delete_agent(deps, ui, ts, ws, agent, typed),
Action::Monitor(verb) => monitor::dispatch(deps, ts, ws, agent, verb),
Action::Fleet(verb) => fleet::dispatch(deps, ts, ws, verb),
Action::AnswerHold { answer, .. } => control::answer_hold(deps, ts, ws, agent, *answer),
Action::Floor { raised, .. } => control::set_floor(deps, ts, ws, agent, *raised),
Action::Ack => wrote(
crate::opslog::ack(root, ts, deps.caller.client.clone()),
Reply::Acked,
),
Action::MarkSeen { .. } => acknowledge(deps, ui, ts, ws, agent),
Action::Pin { pinned, .. } => Ok(pin(deps, ui, ts, ws, *pinned)),
Action::ClearTrail => wrote(
crate::opslog::clear(root, ts, deps.caller.client.clone()),
Reply::TrailCleared,
),
Action::Config(write) => match write {
config::Write::Apply { file, text } => config::apply(deps, ts, ws, file, text),
config::Write::Marks { branch, .. } => config::set_marks(deps, ts, ws, branch),
config::Write::Pick {
role,
provider,
model,
..
} => config::pick_model(deps, ts, ws, &Pick::of(role, provider, model)),
config::Write::Tune(tuning) => config::tune(deps, ts, ws, tuning),
config::Write::Proposal(settle) => outcome(verbs::proposal(
&deps.bound(ws),
root,
ts,
&settle.id,
settle.verdict.flag(),
)),
},
Action::Advertise { tools } => advertise::advertise(deps, tools),
Action::Enroll(request) => enroll::enroll(deps, ts, request),
Action::Login { provider, .. } => login::start(deps, ts, ws, provider),
Action::Route(verb) => routing::route(deps, ts, verb),
}
}