use super::super::App;
use crate::agent::r#loop::AgentEvent;
use crate::tui::state::{ChatMessage, MessageRole, SwarmPhase, SwarmUiStatus};
impl App {
pub(crate) fn auto_continue(
&mut self,
reason: &crate::agent::guard::StopReason,
event_tx: tokio::sync::mpsc::UnboundedSender<AgentEvent>,
) {
self.continuation_count += 1;
let continuation_prompt = format!(
"The previous execution was stopped: {reason}. \
This is auto-continuation round {round}/{max}. \
Review what was accomplished so far and continue the remaining work. \
Focus on completing the original task: {task}",
reason = reason,
round = self.continuation_count,
max = self.config.max_continuations,
task = self.current_task,
);
self.state.messages.push(ChatMessage::text(
MessageRole::System,
format!(
"⟳ Auto-continuing ({}/{}): {}",
self.continuation_count, self.config.max_continuations, reason,
),
));
self.state.input = continuation_prompt;
self.state.cursor = self.state.input.len();
self.submit_message(event_tx);
}
pub(crate) fn fire_pending_dispatch(&mut self, d: crate::app::PendingDispatch) {
use crate::app::PendingDispatch;
let PendingDispatch {
context,
augmented_input,
event_tx,
effective_mode,
agent_name,
additional_agents,
client,
config,
working_dir,
lsp_manager,
trust_level,
cancel,
approval_gate,
approval_req_tx_swarm,
images,
shared_mcp,
shared_skills,
shared_tool_index,
} = d;
let effective_mode = if self.fast_mode {
crate::agent::swarm::config::CollaborationMode::None
} else {
effective_mode
};
if effective_mode.is_parallel() {
let collab_config = self.config.collaboration.clone();
let coordinator = {
let mut swarm_client = client.clone();
swarm_client.model = config.model.clone();
let mut c = crate::agent::swarm::coordinator::SwarmCoordinator::new(
config.clone(),
collab_config,
swarm_client,
working_dir.clone(),
lsp_manager.clone(),
config.agents.clone(),
);
if !agent_name.is_empty() && agent_name != "arbor" {
c = c.with_preferred_agent(agent_name);
}
if !additional_agents.is_empty() {
c = c.with_additional_agents(additional_agents);
}
if let (Some(mcp), Some(skills), Some(idx)) = (
&self.cached_mcp,
&self.cached_skills,
&self.cached_tool_index,
) {
c = c.with_shared_resources(mcp.clone(), skills.clone(), idx.clone());
}
c
}
.with_approval(
approval_gate.shared_mode(),
approval_req_tx_swarm,
self.session_approvals.clone(),
);
self.swarm_knowledge = Some(coordinator.shared_knowledge());
self.state.swarm_status = Some(SwarmUiStatus {
mode_label: format!("{}", effective_mode).to_uppercase(),
agents: Vec::new(),
phase: SwarmPhase::Analyzing,
pending_conflicts: Vec::new(),
});
tokio::spawn(async move {
coordinator
.run_or_recover(context, augmented_input, event_tx, cancel)
.await;
});
} else {
tokio::spawn(async move {
if let Some(mcp) = shared_mcp {
crate::agent::r#loop::run_with_shared_mcp(
crate::agent::r#loop::AgentParams {
client,
config,
context,
user_msg: augmented_input,
working_dir,
event_tx,
cancel,
lsp_manager,
trust_level,
approval_gate,
images,
},
crate::agent::r#loop::SwarmParams {
mcp_manager: mcp,
shared_knowledge: None,
shared_tool_index,
shared_skill_registry: shared_skills,
instruction_rx: None,
},
)
.await;
} else {
crate::agent::r#loop::run_with_mode(crate::agent::r#loop::AgentParams {
client,
config,
context,
user_msg: augmented_input,
working_dir,
event_tx,
cancel,
lsp_manager,
trust_level,
approval_gate,
images,
})
.await;
}
});
}
}
}