feat: refactor auto-review engine to use spawn_subagent for improved thread handling

This commit is contained in:
asepharyana
2026-07-20 17:25:23 +07:00
parent dd7825b481
commit 094eb4b8ba
+58 -54
View File
@@ -19,7 +19,7 @@ use tracing::{debug, info, instrument, warn};
use crate::subagent::context::SubagentContext; use crate::subagent::context::SubagentContext;
use crate::subagent::division::AccessTier; use crate::subagent::division::AccessTier;
use crate::subagent::engine::run_agent; use crate::subagent::spawn::spawn_subagent;
use crate::tools::ToolCtx; use crate::tools::ToolCtx;
use crate::{AgentStatus, TurnEvent}; use crate::{AgentStatus, TurnEvent};
@@ -174,64 +174,19 @@ pub fn spawn_background_review(
model, model,
); );
// 7. Run the subagent engine directly on this thread // 7. Spawn the subagent via spawn_subagent (creates its own OS thread
// (creates its own tokio runtime, calls run_agent with Write tools) // + tokio runtime internally, avoiding nested runtime panics).
let rt = match tokio::runtime::Runtime::new() { let handle = spawn_subagent(
Ok(r) => r,
Err(e) => {
warn!(error = %e, "auto-review: failed to create tokio runtime");
push_event(
&turn_events,
TurnEvent::WorkflowAgentUpdate {
agent_id,
agent_name,
status: AgentStatus::Failed(format!("runtime error: {e}")),
},
);
return;
}
};
let result = rt.block_on(run_agent(
subagent_ctx, subagent_ctx,
"Auto-review and fix issues in the changed files", "Auto-review and fix issues in the changed files".to_string(),
AccessTier::Write, AccessTier::Write,
tool_ctx, tool_ctx,
)); );
// 8. Report results // 8. Report results
match result { let report = match handle.join() {
Ok(report) => { Ok(Ok(r)) => r,
let trimmed = report.trim(); Ok(Err(e)) => {
if trimmed.is_empty() || trimmed.contains("no issues") {
push_event(
&turn_events,
TurnEvent::SystemNote {
kind: "review".into(),
message: "✅ Auto-review: no issues found.".into(),
},
);
info!("auto-review: no issues found");
} else {
push_event(
&turn_events,
TurnEvent::SystemNote {
kind: "review_finding".into(),
message: format!("📋 Auto-review complete:\n{}", trimmed),
},
);
info!("auto-review: completed with findings");
}
push_event(
&turn_events,
TurnEvent::WorkflowAgentUpdate {
agent_id,
agent_name,
status: AgentStatus::Completed,
},
);
}
Err(e) => {
warn!(error = %e, "auto-review subagent failed"); warn!(error = %e, "auto-review subagent failed");
push_event( push_event(
&turn_events, &turn_events,
@@ -248,8 +203,57 @@ pub fn spawn_background_review(
status: AgentStatus::Failed(e.to_string()), status: AgentStatus::Failed(e.to_string()),
}, },
); );
return;
} }
Err(e) => {
warn!(error = ?e, "auto-review subagent panicked");
push_event(
&turn_events,
TurnEvent::SystemNote {
kind: "review".into(),
message: "⚠️ Auto-review agent panicked.".into(),
},
);
push_event(
&turn_events,
TurnEvent::WorkflowAgentUpdate {
agent_id,
agent_name,
status: AgentStatus::Failed("panicked".to_string()),
},
);
return;
}
};
let trimmed = report.trim();
if trimmed.is_empty() || trimmed.to_lowercase().contains("no issues") {
push_event(
&turn_events,
TurnEvent::SystemNote {
kind: "review".into(),
message: "✅ Auto-review: no issues found.".into(),
},
);
info!("auto-review: no issues found");
} else {
push_event(
&turn_events,
TurnEvent::SystemNote {
kind: "review_finding".into(),
message: format!("📋 Auto-review complete:\n{}", trimmed),
},
);
info!("auto-review: completed with findings");
} }
push_event(
&turn_events,
TurnEvent::WorkflowAgentUpdate {
agent_id,
agent_name,
status: AgentStatus::Completed,
},
);
}); });
} }