feat: update README and documentation for new tools and features

- Updated README.md to reflect the addition of 3 new built-in tools, bringing the total to 37.
- Revised architecture documentation to indicate the increase in tool count.
- Enhanced backend documentation with updated line counts for various modules.
- Modified data documentation to change edit log format from JSON to JSONL.
- Updated dependencies documentation to reflect version upgrades for several crates.
- Improved prompts for auto-reviewer, division implementer, planner, tester, and quality reviewer to enforce stricter coding standards regarding linter bypasses.
- Refactored code in various modules to improve clarity and performance, including updates to error handling and tool execution logic.
- Added comprehensive tests for IPC frame serialization and deserialization.
This commit is contained in:
asepharyana
2026-07-13 14:39:39 +07:00
parent 00e29139c5
commit 1d50b94eec
23 changed files with 327 additions and 176 deletions
+8 -7
View File
@@ -93,13 +93,14 @@ fn make_division_phase(
/// context to flow through the pipeline.
///
/// Returns a consolidated executive summary string.
#[allow(clippy::ref_option)]
pub fn run_company_pipeline(
user_request: &str,
session_dir: &std::path::Path,
workspaces: &[std::path::PathBuf],
turn_events: Option<&Arc<Mutex<std::collections::VecDeque<crate::app::state::runtime::TurnEvent>>>>,
abort_flag: &Option<Arc<AtomicBool>>,
custom_specialists: HashMap<String, Vec<(String, String)>>,
custom_specialists: &HashMap<String, Vec<(String, String)>>,
) -> anyhow::Result<String> {
let divisions = division::all_divisions();
@@ -179,20 +180,21 @@ pub fn run_company_pipeline(
.map(|f| f.clone())
.unwrap_or_default();
Ok(build_executive_summary(user_request, &results, &all_findings, &divisions, &custom_specialists))
Ok(build_executive_summary(user_request, &results, &all_findings, &divisions, custom_specialists))
}
/// Run a quick company pipeline that skips non-essential divisions
/// for simple tasks. Flow: Strategy → Engineering → Quality.
///
/// This is for smaller tasks where security audit and full docs are overkill.
#[allow(clippy::ref_option)]
pub fn run_company_pipeline_quick(
user_request: &str,
session_dir: &std::path::Path,
workspaces: &[std::path::PathBuf],
turn_events: Option<&Arc<Mutex<std::collections::VecDeque<crate::app::state::runtime::TurnEvent>>>>,
abort_flag: &Option<Arc<AtomicBool>>,
custom_specialists: HashMap<String, Vec<(String, String)>>,
custom_specialists: &HashMap<String, Vec<(String, String)>>,
) -> anyhow::Result<String> {
let divisions = division::all_divisions();
let quick_divisions = &divisions[..3];
@@ -252,7 +254,7 @@ pub fn run_company_pipeline_quick(
.map(|f| f.clone())
.unwrap_or_default();
Ok(build_executive_summary(user_request, &results, &all_findings, quick_divisions, &custom_specialists))
Ok(build_executive_summary(user_request, &results, &all_findings, quick_divisions, custom_specialists))
}
/// Build a compressed executive summary from pipeline results.
@@ -277,8 +279,7 @@ fn build_executive_summary(
let mut start_index = 0;
for div in divisions {
let count = custom_specialists.get(div.name)
.map(Vec::len)
.unwrap_or(0);
.map_or(0, Vec::len);
let mut division_verdicts = Vec::new();
for offset in 0..count {
@@ -393,7 +394,7 @@ mod tests {
("Custom Label".to_string(), "Custom Focus Description".to_string())
]
);
let specs = make_division_specialists(div, "Test Request", &custom.get("Strategy").unwrap());
let specs = make_division_specialists(div, "Test Request", custom.get("Strategy").unwrap());
assert_eq!(specs.len(), 1);
if let ScriptPrimitive::Agent(prompt) = &specs[0] {
assert!(prompt.contains("Custom Label"));
+24 -26
View File
@@ -98,7 +98,7 @@ pub type LiveStateFn = Arc<dyn Fn(String, String, AgentStatus) + Send + Sync>;
/// a stuck stage from blocking the entire pipeline forever.
///
/// Return: the agent's text output, or an error on failure.
#[allow(clippy::too_many_lines, clippy::too_many_arguments)]
#[allow(clippy::too_many_lines, clippy::too_many_arguments, clippy::ref_option)]
fn spawn_single_agent(
agent_id: &str,
agent_name: &str,
@@ -185,7 +185,7 @@ fn spawn_single_agent(
// Link the shared findings Arc so note_finding calls within this
// subagent write into the same vec visible to sibling agents.
ctx.workflow_findings = Some(findings.clone());
ctx.abort_flag = abort_flag.clone();
ctx.abort_flag.clone_from(abort_flag);
// Create an mpsc channel and drain events in a background thread.
// The drain thread also pushes intra-division progress updates to the
@@ -269,34 +269,30 @@ fn spawn_single_agent(
let deadline = Duration::from_millis(timeout);
let mut elapsed = Duration::ZERO;
loop {
match done_rx.recv_timeout(poll_interval) {
Ok(r) => break r,
Err(_) => {
elapsed += poll_interval;
if elapsed >= deadline {
break Err(anyhow::anyhow!(
"subagent '{bg_name}' timed out after {timeout}ms",
));
}
if bg_abort.as_ref().is_some_and(|f| f.load(Ordering::SeqCst)) {
break Err(anyhow::anyhow!(
"subagent '{bg_name}' aborted by user",
));
}
}
if let Ok(r) = done_rx.recv_timeout(poll_interval) {
break r;
}
elapsed += poll_interval;
if elapsed >= deadline {
break Err(anyhow::anyhow!(
"subagent '{bg_name}' timed out after {timeout}ms",
));
}
if bg_abort.as_ref().is_some_and(|f| f.load(Ordering::SeqCst)) {
break Err(anyhow::anyhow!(
"subagent '{bg_name}' aborted by user",
));
}
}
} else {
loop {
match done_rx.recv_timeout(poll_interval) {
Ok(r) => break r,
Err(_) => {
if bg_abort.as_ref().is_some_and(|f| f.load(Ordering::SeqCst)) {
break Err(anyhow::anyhow!(
"subagent '{bg_name}' aborted by user",
));
}
}
if let Ok(r) = done_rx.recv_timeout(poll_interval) {
break r;
}
if bg_abort.as_ref().is_some_and(|f| f.load(Ordering::SeqCst)) {
break Err(anyhow::anyhow!(
"subagent '{bg_name}' aborted by user",
));
}
}
};
@@ -358,6 +354,7 @@ type ParallelResult = (usize, anyhow::Result<Vec<String>>);
/// Return: a `Vec<String>` of all agent outputs (or error strings) in
/// the order they were submitted.
#[allow(clippy::too_many_arguments)]
#[allow(clippy::ref_option, clippy::too_many_lines)]
pub fn execute_primitive(
primitive: &ScriptPrimitive,
args: &HashMap<String, String>,
@@ -529,6 +526,7 @@ pub fn run_workflow(
/// `spawn_agents` invocations remain fully isolated.
///
/// Return: a human-readable summary string.
#[allow(clippy::ref_option)]
pub fn run_workflow_tracked(
script: &WorkflowScript,
args: &HashMap<String, String>,