huskies: merge 759
This commit is contained in:
@@ -30,6 +30,19 @@ impl AgentPool {
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// Return story IDs of merge jobs currently in the `Running` state.
|
||||
///
|
||||
/// Used by `list_agents` and `get_pipeline_status` to surface in-flight
|
||||
/// deterministic merges that hold the merge lock but have no agent entry.
|
||||
pub fn list_running_merges(&self) -> Result<Vec<String>, String> {
|
||||
let jobs = self.merge_jobs.lock().map_err(|e| e.to_string())?;
|
||||
Ok(jobs
|
||||
.values()
|
||||
.filter(|job| matches!(job.status, crate::agents::merge::MergeJobStatus::Running))
|
||||
.map(|job| job.story_id.clone())
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// List all agents with their status.
|
||||
pub fn list_agents(&self) -> Result<Vec<AgentInfo>, String> {
|
||||
let agents = self.agents.lock().map_err(|e| e.to_string())?;
|
||||
|
||||
@@ -87,25 +87,38 @@ pub(crate) async fn tool_stop_agent(args: &Value, ctx: &AppContext) -> Result<St
|
||||
pub(crate) fn tool_list_agents(ctx: &AppContext) -> Result<String, String> {
|
||||
let project_root = ctx.services.agents.get_project_root(&ctx.state).ok();
|
||||
let agents = ctx.services.agents.list_agents()?;
|
||||
serde_json::to_string_pretty(&json!(
|
||||
agents
|
||||
.iter()
|
||||
.filter(|a| {
|
||||
project_root
|
||||
.as_deref()
|
||||
.map(|root| !crate::service::agents::is_archived(root, &a.story_id))
|
||||
.unwrap_or(true)
|
||||
})
|
||||
.map(|a| json!({
|
||||
let mut entries: Vec<serde_json::Value> = agents
|
||||
.iter()
|
||||
.filter(|a| {
|
||||
project_root
|
||||
.as_deref()
|
||||
.map(|root| !crate::service::agents::is_archived(root, &a.story_id))
|
||||
.unwrap_or(true)
|
||||
})
|
||||
.map(|a| {
|
||||
json!({
|
||||
"story_id": a.story_id,
|
||||
"agent_name": a.agent_name,
|
||||
"status": a.status.to_string(),
|
||||
"session_id": a.session_id,
|
||||
"worktree_path": a.worktree_path,
|
||||
}))
|
||||
.collect::<Vec<_>>()
|
||||
))
|
||||
.map_err(|e| format!("Serialization error: {e}"))
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Append a synthetic entry for each deterministic merge holding the merge lock.
|
||||
let running_merges = ctx.services.agents.list_running_merges()?;
|
||||
for story_id in running_merges {
|
||||
entries.push(json!({
|
||||
"story_id": story_id,
|
||||
"agent_name": "deterministic-merge",
|
||||
"status": "Running",
|
||||
"session_id": null,
|
||||
"worktree_path": null,
|
||||
}));
|
||||
}
|
||||
|
||||
serde_json::to_string_pretty(&json!(entries)).map_err(|e| format!("Serialization error: {e}"))
|
||||
}
|
||||
|
||||
/// Read agent session logs from disk and return a human-readable timeline.
|
||||
|
||||
@@ -156,6 +156,7 @@ pub(crate) fn tool_list_upcoming(ctx: &AppContext) -> Result<String, String> {
|
||||
|
||||
pub(crate) fn tool_get_pipeline_status(ctx: &AppContext) -> Result<String, String> {
|
||||
let state = load_pipeline_state(ctx)?;
|
||||
let running_merges = ctx.services.agents.list_running_merges()?;
|
||||
|
||||
fn map_items(items: &[crate::http::workflow::UpcomingStory], stage: &str) -> Vec<Value> {
|
||||
items
|
||||
@@ -203,6 +204,7 @@ pub(crate) fn tool_get_pipeline_status(ctx: &AppContext) -> Result<String, Strin
|
||||
"active": active,
|
||||
"backlog": backlog,
|
||||
"backlog_count": backlog.len(),
|
||||
"deterministic_merges_in_flight": running_merges,
|
||||
}))
|
||||
.map_err(|e| format!("Serialization error: {e}"))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user