use crate::config::{Action, Event, Workflow};
use crate::prompt::{ChildDispatchRequest, Deps, Error, child_dispatch, compactor};
use std::path::Path;
pub(in crate::prompt::dispatch) fn run_flush(
workspace: &Path,
agent_id: &str,
worktree: &Path,
workflow: &Workflow,
deps: &Deps<'_>,
) -> Result<(), Error> {
if workflow.compaction.is_none() {
return Ok(());
}
let state = compactor::state(worktree, agent_id, deps.clock.now_unix(), false, deps.git)?;
if !compactor::due(workflow.compaction.as_ref(), &state) {
return Ok(());
}
for action in flush_actions(workflow) {
execute_flush(&action, workspace, agent_id, worktree, deps)?;
}
Ok(())
}
fn flush_actions(workflow: &Workflow) -> Vec<Action> {
let bound = workflow.actions_for(Event::WorkerFlush);
if bound.is_empty() {
vec![Action::Dispatch {
role: compactor::COMPACTOR_ROLE.to_string(),
with: None,
mode: None,
}]
} else {
bound
}
}
fn execute_flush(
action: &Action,
workspace: &Path,
agent_id: &str,
worktree: &Path,
deps: &Deps<'_>,
) -> Result<(), Error> {
match action {
Action::Dispatch { role, .. } if role == compactor::COMPACTOR_ROLE => {
dispatch_compactor(workspace, agent_id, worktree, deps)
}
other => Err(Error::ActionUnsupported {
action: format!("{other:?}"),
event: Event::WorkerFlush.as_str(),
}),
}
}
fn dispatch_compactor(
workspace: &Path,
agent_id: &str,
worktree: &Path,
deps: &Deps<'_>,
) -> Result<(), Error> {
let goal = compactor::compactor_goal(agent_id);
let req = ChildDispatchRequest {
repo: workspace,
parent_branch: agent_id,
parent_worktree: worktree,
role: compactor::COMPACTOR_ROLE,
goal: &goal,
fork_point: None,
};
child_dispatch::run_procedure(&req, deps.git, deps.clock, deps.id_gen, deps.launcher)
}