huskies: merge 626_refactor_introduce_services_bundle_and_migrate_appcontext_matrix_transport

This commit is contained in:
dave
2026-04-25 15:04:37 +00:00
parent aeff0b55be
commit 4b089c1ed8
21 changed files with 403 additions and 339 deletions
+32 -18
View File
@@ -14,8 +14,9 @@ pub(super) async fn tool_start_agent(args: &Value, ctx: &AppContext) -> Result<S
.ok_or("Missing required argument: story_id")?;
let agent_name = args.get("agent_name").and_then(|v| v.as_str());
let project_root = ctx.agents.get_project_root(&ctx.state)?;
let project_root = ctx.services.agents.get_project_root(&ctx.state)?;
let info = ctx
.services
.agents
.start_agent(&project_root, story_id, agent_name, None, None)
.await?;
@@ -67,8 +68,9 @@ pub(super) async fn tool_stop_agent(args: &Value, ctx: &AppContext) -> Result<St
.and_then(|v| v.as_str())
.ok_or("Missing required argument: agent_name")?;
let project_root = ctx.agents.get_project_root(&ctx.state)?;
ctx.agents
let project_root = ctx.services.agents.get_project_root(&ctx.state)?;
ctx.services
.agents
.stop_agent(&project_root, story_id, agent_name)
.await?;
@@ -78,8 +80,8 @@ pub(super) async fn tool_stop_agent(args: &Value, ctx: &AppContext) -> Result<St
}
pub(super) fn tool_list_agents(ctx: &AppContext) -> Result<String, String> {
let project_root = ctx.agents.get_project_root(&ctx.state).ok();
let agents = ctx.agents.list_agents()?;
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()
@@ -125,7 +127,7 @@ pub(super) async fn tool_get_agent_output(
.map(|n| n as usize);
let filter = args.get("filter").and_then(|v| v.as_str());
let project_root = ctx.agents.get_project_root(&ctx.state)?;
let project_root = ctx.services.agents.get_project_root(&ctx.state)?;
// Collect all matching log files, oldest first.
let log_files = agent_log::list_story_log_files(&project_root, story_id, agent_name_filter);
@@ -149,7 +151,7 @@ pub(super) async fn tool_get_agent_output(
// writer failed and nothing was persisted to disk.
if log_files.is_empty()
&& let Some(agent_name) = agent_name_filter
&& let Ok(live_events) = ctx.agents.drain_events(story_id, agent_name)
&& let Ok(live_events) = ctx.services.agents.drain_events(story_id, agent_name)
&& !live_events.is_empty()
{
all_lines.push(format!("=== {agent_name} (live) ==="));
@@ -195,7 +197,7 @@ pub(super) async fn tool_get_agent_output(
}
pub(super) fn tool_get_agent_config(ctx: &AppContext) -> Result<String, String> {
let project_root = ctx.agents.get_project_root(&ctx.state)?;
let project_root = ctx.services.agents.get_project_root(&ctx.state)?;
let config = ProjectConfig::load(&project_root)?;
// Collect available (idle) agent names across all stages so the caller can
@@ -207,7 +209,11 @@ pub(super) fn tool_get_agent_config(ctx: &AppContext) -> Result<String, String>
PipelineStage::Mergemaster,
PipelineStage::Other,
] {
if let Ok(names) = ctx.agents.available_agents_for_stage(&config, stage) {
if let Ok(names) = ctx
.services
.agents
.available_agents_for_stage(&config, stage)
{
available_names.extend(names);
}
}
@@ -249,7 +255,7 @@ pub(super) fn tool_get_agent_remaining_turns_and_budget(
.ok_or("Missing required argument: agent_name")?;
// Verify the agent exists and is running/pending.
let agents = ctx.agents.list_agents()?;
let agents = ctx.services.agents.list_agents()?;
let agent_info = agents
.iter()
.find(|a| a.story_id == story_id && a.agent_name == agent_name)
@@ -275,7 +281,7 @@ pub(super) fn tool_get_agent_remaining_turns_and_budget(
));
}
let project_root = ctx.agents.get_project_root(&ctx.state)?;
let project_root = ctx.services.agents.get_project_root(&ctx.state)?;
let config = ProjectConfig::load(&project_root)?;
// Find the agent config (max_turns, max_budget_usd).
@@ -341,6 +347,7 @@ pub(super) async fn tool_wait_for_agent(args: &Value, ctx: &AppContext) -> Resul
.unwrap_or(300_000); // default: 5 minutes
let info = ctx
.services
.agents
.wait_for_agent(story_id, agent_name, timeout_ms)
.await?;
@@ -377,8 +384,12 @@ pub(super) async fn tool_create_worktree(args: &Value, ctx: &AppContext) -> Resu
.and_then(|v| v.as_str())
.ok_or("Missing required argument: story_id")?;
let project_root = ctx.agents.get_project_root(&ctx.state)?;
let info = ctx.agents.create_worktree(&project_root, story_id).await?;
let project_root = ctx.services.agents.get_project_root(&ctx.state)?;
let info = ctx
.services
.agents
.create_worktree(&project_root, story_id)
.await?;
serde_json::to_string_pretty(&json!({
"story_id": story_id,
@@ -390,7 +401,7 @@ pub(super) async fn tool_create_worktree(args: &Value, ctx: &AppContext) -> Resu
}
pub(super) fn tool_list_worktrees(ctx: &AppContext) -> Result<String, String> {
let project_root = ctx.agents.get_project_root(&ctx.state)?;
let project_root = ctx.services.agents.get_project_root(&ctx.state)?;
let entries = worktree::list_worktrees(&project_root)?;
serde_json::to_string_pretty(&json!(
@@ -411,7 +422,7 @@ pub(super) async fn tool_remove_worktree(args: &Value, ctx: &AppContext) -> Resu
.and_then(|v| v.as_str())
.ok_or("Missing required argument: story_id")?;
let project_root = ctx.agents.get_project_root(&ctx.state)?;
let project_root = ctx.services.agents.get_project_root(&ctx.state)?;
let config = ProjectConfig::load(&project_root)?;
worktree::remove_worktree_by_story_id(&project_root, story_id, &config).await?;
@@ -876,7 +887,8 @@ stage = "coder"
use crate::agents::AgentStatus;
let tmp = tempfile::tempdir().unwrap();
let ctx = test_ctx(tmp.path());
ctx.agents
ctx.services
.agents
.inject_test_agent("41_story", "worker", AgentStatus::Completed);
let result = tool_wait_for_agent(
@@ -980,7 +992,8 @@ stage = "coder"
use crate::agents::AgentStatus;
let tmp = tempfile::tempdir().unwrap();
let ctx = test_ctx(tmp.path());
ctx.agents
ctx.services
.agents
.inject_test_agent("42_story", "coder-1", AgentStatus::Completed);
let result = tool_get_agent_remaining_turns_and_budget(
@@ -1004,7 +1017,8 @@ stage = "coder"
let ctx = test_ctx(tmp.path());
ctx.store
.set("project_root", json!(tmp.path().to_string_lossy().as_ref()));
ctx.agents
ctx.services
.agents
.inject_test_agent("42_story", "coder-1", AgentStatus::Running);
let result = tool_get_agent_remaining_turns_and_budget(