feat(hive-mind): implement multi-agent orchestration with cognitive cycles

- Introduced a new hive-mind architecture that allows the Core Intelligence to issue directives to anonymous processing nodes.
- Each node executes its directive and merges output into a collective state, visible to all nodes in real-time.
- Added support for dynamic cognitive cycles, enabling flexible task management.
- Implemented documentation generation for hive-mind runs, ensuring a durable record of decisions and actions.
- Refactored existing company pipeline tools to align with the new hive-mind structure, replacing division-specific prompts with a more generalized approach.
- Updated workflow rendering to accommodate hive-mind nodes and their system-assigned designations.
- Enhanced error handling and validation for cognitive cycle plans.
This commit is contained in:
asepharyana
2026-07-14 08:12:43 +07:00
parent b1e0dcae14
commit 25f084f9db
23 changed files with 895 additions and 1225 deletions
+46 -77
View File
@@ -143,6 +143,46 @@ pub fn spawn_quick_review(
/// ─── Background Subagent Spawners (async, report via `SystemNote`) ───
///
/// Run a subagent built from `def`, retrying once if the first attempt
/// fails. Background subagents call this instead of running once and
/// silently swallowing the error into a note string, so a single transient
/// LLM/tool failure doesn't just disappear.
///
/// Return: `Ok(output)` if either attempt succeeded, `Err(message)`
/// describing the final failure if both attempts failed.
fn run_subagent_with_retry(
def: &AgentDefinition,
session_dir: &Path,
workspaces: &[std::path::PathBuf],
label: &str,
) -> Result<String, String> {
let mut last_err = String::new();
for attempt in 1..=2 {
let mut ctx = build_subagent_context(def);
ctx.session_dir = session_dir.to_path_buf();
ctx.workspaces = workspaces.to_vec();
let (tx, mut rx) = tokio::sync::mpsc::channel(32);
let drain_label = label.to_string();
let _drain = std::thread::spawn(move || {
while let Some(event) = rx.blocking_recv() {
if let SubagentEvent::StepFailed { step, error } = &event {
tracing::warn!("[{drain_label}] step {step} failed: {error}");
}
}
});
match run_subagent(&ctx, &tx) {
Ok(output) => return Ok(output),
Err(e) => {
tracing::warn!("[{label}] attempt {attempt}/2 failed: {e}");
last_err = e.to_string();
}
}
}
Err(format!("failed after 2 attempts: {last_err}"))
}
/// Spawn a background subagent that generates tests for modified files.
///
/// Uses the test-generator prompt and has read-write access so it can
@@ -184,40 +224,13 @@ pub fn spawn_background_test_gen(
.with_system_prompt(prompt)
;
let mut ctx = build_subagent_context(&def);
ctx.session_dir = sd;
ctx.workspaces = ws;
let (tx, mut rx) = tokio::sync::mpsc::channel(32);
let _drain = std::thread::spawn(move || {
while let Some(event) = rx.blocking_recv() {
match &event {
SubagentEvent::ToolCall { tool, .. } => {
tracing::debug!("[bg-test-gen] tool: {}", tool);
}
SubagentEvent::ToolResult { tool, .. } => {
tracing::debug!("[bg-test-gen] result: {}", tool);
}
SubagentEvent::StepCompleted { .. } => {
tracing::trace!("[bg-test-gen] step done");
}
SubagentEvent::StepFailed { step, error } => {
tracing::warn!("[bg-test-gen] step {} failed: {}", step, error);
}
SubagentEvent::Completed { .. } => {
tracing::debug!("[bg-test-gen] completed");
}
}
}
});
let result = run_subagent(&ctx, &tx);
let result = run_subagent_with_retry(&def, &sd, &ws, "bg-test-gen");
let message = match &result {
Ok(output) => {
let first = output.lines().next().unwrap_or(output);
format!("Auto test-gen: {first}")
}
Err(e) => format!("Auto test-gen failed: {e}"),
Err(e) => format!("ESCALATED: Auto test-gen {e}"),
};
if let Ok(mut q) = events.lock() {
@@ -264,35 +277,13 @@ pub fn spawn_background_arch_review(
.with_system_prompt(prompt)
;
let mut ctx = build_subagent_context(&def);
ctx.session_dir = sd;
ctx.workspaces = ws;
let (tx, mut rx) = tokio::sync::mpsc::channel(32);
let _drain = std::thread::spawn(move || {
while let Some(event) = rx.blocking_recv() {
match &event {
SubagentEvent::ToolCall { tool, .. } => {
tracing::debug!("[bg-arch] tool: {}", tool);
}
SubagentEvent::ToolResult { tool, .. } => {
tracing::debug!("[bg-arch] result: {}", tool);
}
SubagentEvent::Completed { .. } => {
tracing::debug!("[bg-arch] completed");
}
_ => {}
}
}
});
let result = run_subagent(&ctx, &tx);
let result = run_subagent_with_retry(&def, &sd, &ws, "bg-arch-review");
let message = match &result {
Ok(output) => {
let first = output.lines().next().unwrap_or(output);
format!("Architecture review: {first}")
}
Err(e) => format!("Architecture review failed: {e}"),
Err(e) => format!("ESCALATED: Architecture review {e}"),
};
if let Ok(mut q) = events.lock() {
@@ -350,35 +341,13 @@ pub fn spawn_background_security_review(
.with_system_prompt(prompt)
;
let mut ctx = build_subagent_context(&def);
ctx.session_dir = sd;
ctx.workspaces = ws;
let (tx, mut rx) = tokio::sync::mpsc::channel(32);
let _drain = std::thread::spawn(move || {
while let Some(event) = rx.blocking_recv() {
match &event {
SubagentEvent::ToolCall { tool, .. } => {
tracing::debug!("[bg-security] tool: {}", tool);
}
SubagentEvent::ToolResult { tool, .. } => {
tracing::debug!("[bg-security] result: {}", tool);
}
SubagentEvent::Completed { .. } => {
tracing::debug!("[bg-security] completed");
}
_ => {}
}
}
});
let result = run_subagent(&ctx, &tx);
let result = run_subagent_with_retry(&def, &sd, &ws, "bg-security-review");
let message = match &result {
Ok(output) => {
let first = output.lines().next().unwrap_or(output);
format!("Security review: {first}")
}
Err(e) => format!("Security review failed: {e}"),
Err(e) => format!("ESCALATED: Security review {e}"),
};
if let Ok(mut q) = events.lock() {