refactor: improve code readability and consistency across multiple files
This commit is contained in:
@@ -18,7 +18,15 @@ impl BashControl {
|
||||
jobs: Mutex::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for BashControl {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl BashControl {
|
||||
/// Register a new background job.
|
||||
pub fn register(&self, job: Arc<BashJob>) {
|
||||
if let Ok(mut guard) = self.jobs.lock() {
|
||||
|
||||
@@ -33,18 +33,38 @@ pub fn spawn_bash_job(cmd: String) -> Arc<BashJob> {
|
||||
cancelled: AtomicBool::new(false),
|
||||
});
|
||||
|
||||
// Spawn a monitor thread (in production this would use an async task)
|
||||
// Spawn a monitor thread using try_wait() polling so the lock is never
|
||||
// held across a blocking wait, allowing cancel() to acquire the lock.
|
||||
let job_clone = Arc::clone(&job);
|
||||
std::thread::spawn(move || {
|
||||
let mut guard = match job_clone.process.lock() {
|
||||
Ok(g) => g,
|
||||
Err(poisoned) => {
|
||||
error!("bgbash job mutex poisoned, recovering");
|
||||
poisoned.into_inner()
|
||||
loop {
|
||||
let mut exited = false;
|
||||
{
|
||||
let mut guard = match job_clone.process.lock() {
|
||||
Ok(g) => g,
|
||||
Err(poisoned) => {
|
||||
error!("bgbash job mutex poisoned, recovering");
|
||||
poisoned.into_inner()
|
||||
}
|
||||
};
|
||||
if let Some(ref mut child) = *guard {
|
||||
match child.try_wait() {
|
||||
Ok(Some(_)) => exited = true,
|
||||
Ok(None) => {} // still running
|
||||
Err(e) => {
|
||||
error!("bgbash wait error: {e}");
|
||||
exited = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
exited = true; // no child process
|
||||
}
|
||||
} // lock is dropped here — cancel() can now acquire it
|
||||
|
||||
if exited || job_clone.cancelled.load(Ordering::SeqCst) {
|
||||
break;
|
||||
}
|
||||
};
|
||||
if let Some(ref mut child) = *guard {
|
||||
let _ = child.wait();
|
||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -69,8 +89,6 @@ impl BashJob {
|
||||
let Ok(mut guard) = self.process.lock() else {
|
||||
return false;
|
||||
};
|
||||
guard.as_mut().map_or(false, |c| {
|
||||
matches!(c.try_wait(), Ok(None))
|
||||
})
|
||||
guard.as_mut().is_some_and(|c| matches!(c.try_wait(), Ok(None)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ impl LlmClient {
|
||||
loop {
|
||||
attempt += 1;
|
||||
|
||||
if let Some(ref flag) = abort_flag {
|
||||
if let Some(flag) = abort_flag {
|
||||
if flag.load(std::sync::atomic::Ordering::Relaxed) {
|
||||
anyhow::bail!("aborted");
|
||||
}
|
||||
@@ -267,7 +267,7 @@ impl LlmClient {
|
||||
}
|
||||
|
||||
if meaningful_content {
|
||||
if let Some(ref flag) = abort_flag {
|
||||
if let Some(flag) = abort_flag {
|
||||
if flag.load(std::sync::atomic::Ordering::Relaxed) {
|
||||
return Err(anyhow::anyhow!("aborted"));
|
||||
}
|
||||
|
||||
@@ -19,6 +19,15 @@ impl LspManager {
|
||||
clients: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for LspManager {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl LspManager {
|
||||
|
||||
pub fn start(&mut self, language: &str, command: &str, args: &[String]) -> anyhow::Result<()> {
|
||||
let client = LspClient::start(command, args)?;
|
||||
@@ -31,7 +40,7 @@ impl LspManager {
|
||||
}
|
||||
|
||||
pub fn shutdown_all(&mut self) {
|
||||
for (_lang, client) in &self.clients {
|
||||
for client in self.clients.values() {
|
||||
let _ = client.shutdown();
|
||||
}
|
||||
self.clients.clear();
|
||||
|
||||
@@ -22,6 +22,15 @@ impl McpManager {
|
||||
servers: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for McpManager {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl McpManager {
|
||||
|
||||
pub fn register(&mut self, name: &str, transport: &str) {
|
||||
self.servers.insert(
|
||||
|
||||
@@ -26,7 +26,7 @@ const MAX_ITERATIONS: u32 = 25;
|
||||
/// a. Call the LLM (non-streaming) with accumulated messages + tool defs.
|
||||
/// b. If the response has no tool calls → return the text content.
|
||||
/// c. Otherwise execute each tool call and append the result as a
|
||||
/// tool-role message.
|
||||
/// tool-role message.
|
||||
/// d. If the response also contained text, append an assistant message.
|
||||
/// 4. If the loop exits naturally, return the iteration-limit message.
|
||||
pub async fn run_agent(
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//!
|
||||
//! Flow: `resolve_subagent_provider` is called at startup to pick a provider
|
||||
//! + model → `SubagentProvider` wraps that pair around an `LlmClient` for use
|
||||
//! inside the subagent engine loop.
|
||||
//! inside the subagent engine loop.
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//! Subagent workspace management — create isolated workspaces for subagents.
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
/// Create an isolated workspace directory for a subagent.
|
||||
pub fn create_subagent_workspace(base_dir: &PathBuf, agent_id: &str) -> anyhow::Result<PathBuf> {
|
||||
pub fn create_subagent_workspace(base_dir: &Path, agent_id: &str) -> anyhow::Result<PathBuf> {
|
||||
let ws = base_dir.join("subagent-workspaces").join(agent_id);
|
||||
std::fs::create_dir_all(&ws)?;
|
||||
Ok(ws)
|
||||
|
||||
@@ -14,6 +14,15 @@ impl LiveHiveMind {
|
||||
nodes: Mutex::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for LiveHiveMind {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl LiveHiveMind {
|
||||
|
||||
pub fn set_status(&self, agent_id: &str, status: &str) {
|
||||
if let Ok(mut guard) = self.nodes.lock() {
|
||||
|
||||
Reference in New Issue
Block a user