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:
+25
-88
@@ -4,8 +4,9 @@
|
||||
//! panel showing agent statuses, findings count, session counters, and
|
||||
//! usage hints.
|
||||
//!
|
||||
//! Design: agents are shown as compact cards with state-colored badges.
|
||||
//! The division pipeline mode adds a visual pipeline flow with arrows.
|
||||
//! Design: agents are shown as compact cards with state-colored badges,
|
||||
//! including hive-mind nodes (named by their system-assigned designation,
|
||||
//! e.g. `"Node-0-1"`).
|
||||
|
||||
use ratatui::layout::Rect;
|
||||
use ratatui::style::{Style, Modifier};
|
||||
@@ -43,29 +44,12 @@ fn state_color(state: AgentState) -> Color {
|
||||
}
|
||||
}
|
||||
|
||||
/// Detect if the current workflow looks like a company pipeline.
|
||||
fn is_company_pipeline(agents: &[crate::app::workflow::engine::WorkflowAgent]) -> bool {
|
||||
if agents.is_empty() {
|
||||
return false;
|
||||
}
|
||||
let division_keywords = ["Strategy", "Engineering", "Quality", "Security", "Documentation"];
|
||||
agents.iter().any(|a| {
|
||||
division_keywords.iter().any(|k| a.name.contains(k))
|
||||
})
|
||||
}
|
||||
|
||||
/// Render the workflow status panel.
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn draw_workflow_panel(frame: &mut Frame, area: Rect, state: &crate::app::state::rest::AppStateRest) {
|
||||
use ratatui::layout::{Constraint, Direction, Layout};
|
||||
|
||||
let is_company = is_company_pipeline(&state.workflow_engine.agents);
|
||||
|
||||
let title = if is_company {
|
||||
Span::styled(" 🏢 Pipeline ", Style::default().fg(Theme::PRIMARY).add_modifier(Modifier::BOLD))
|
||||
} else {
|
||||
Span::styled(" ⚙ Workflow ", Style::default().fg(Theme::PRIMARY).add_modifier(Modifier::BOLD))
|
||||
};
|
||||
let title = Span::styled(" ⚙ Workflow ", Style::default().fg(Theme::PRIMARY).add_modifier(Modifier::BOLD));
|
||||
|
||||
let block = Block::default()
|
||||
.borders(Borders::ALL)
|
||||
@@ -87,74 +71,27 @@ pub fn draw_workflow_panel(frame: &mut Frame, area: Rect, state: &crate::app::st
|
||||
// ── Header area ──────────────────────────────────────────────────────
|
||||
let mut header_lines: Vec<Line> = Vec::new();
|
||||
|
||||
if is_company {
|
||||
// Division pipeline overview
|
||||
let agents = &state.workflow_engine.agents;
|
||||
let mut pipe_spans: Vec<Span> = Vec::new();
|
||||
for (i, agent) in agents.iter().enumerate() {
|
||||
if i > 0 {
|
||||
pipe_spans.push(Span::styled(
|
||||
" ",
|
||||
Style::default().fg(Theme::TEXT_DIM),
|
||||
));
|
||||
}
|
||||
let icon = state_icon(agent.status.state);
|
||||
let color = state_color(agent.status.state);
|
||||
let modif = match agent.status.state {
|
||||
AgentState::Idle => Modifier::empty(),
|
||||
_ => Modifier::BOLD,
|
||||
};
|
||||
pipe_spans.push(Span::styled(
|
||||
format!("{} {} ", icon, agent.name.chars().take(10).collect::<String>()),
|
||||
Style::default().fg(color).add_modifier(modif),
|
||||
));
|
||||
if i < agents.len().saturating_sub(1) {
|
||||
pipe_spans.push(Span::styled(
|
||||
"→",
|
||||
Style::default().fg(Theme::TEXT_DIM),
|
||||
));
|
||||
}
|
||||
}
|
||||
header_lines.push(Line::from(pipe_spans));
|
||||
header_lines.push(Line::from(vec![
|
||||
Span::styled("Status: ", Style::default().fg(Theme::TEXT_DIM)),
|
||||
if state.turn_in_flight() {
|
||||
Span::styled("● Running", Style::default().fg(Theme::WARNING).add_modifier(Modifier::BOLD))
|
||||
} else {
|
||||
Span::styled("● Idle", Style::default().fg(Theme::SUCCESS))
|
||||
},
|
||||
Span::raw(" "),
|
||||
Span::styled(
|
||||
format!("Agents: {} | Findings: {}",
|
||||
state.workflow_engine.agents.len(),
|
||||
state.workflow_engine.findings.len(),
|
||||
),
|
||||
Style::default().fg(Theme::TEXT_DIM),
|
||||
header_lines.push(Line::from(vec![
|
||||
Span::styled("/workflow run ", Style::default().fg(Theme::PRIMARY).add_modifier(Modifier::BOLD)),
|
||||
Span::styled("<prompt>", Style::default().fg(Theme::TEXT_DIM)),
|
||||
Span::styled(" · Esc to close", Style::default().fg(Theme::TEXT_DIM)),
|
||||
]));
|
||||
header_lines.push(Line::from(vec![
|
||||
Span::styled("Status: ", Style::default().fg(Theme::TEXT_DIM)),
|
||||
if state.turn_in_flight() {
|
||||
Span::styled("● Running", Style::default().fg(Theme::WARNING).add_modifier(Modifier::BOLD))
|
||||
} else {
|
||||
Span::styled("● Idle", Style::default().fg(Theme::SUCCESS))
|
||||
},
|
||||
Span::raw(" "),
|
||||
Span::styled(
|
||||
format!("Agents: {} | Findings: {}",
|
||||
state.workflow_engine.agents.len(),
|
||||
state.workflow_engine.findings.len(),
|
||||
),
|
||||
]));
|
||||
} else {
|
||||
header_lines.push(Line::from(vec![
|
||||
Span::styled("/workflow run ", Style::default().fg(Theme::PRIMARY).add_modifier(Modifier::BOLD)),
|
||||
Span::styled("<prompt>", Style::default().fg(Theme::TEXT_DIM)),
|
||||
Span::styled(" · Esc to close", Style::default().fg(Theme::TEXT_DIM)),
|
||||
]));
|
||||
header_lines.push(Line::from(vec![
|
||||
Span::styled("Status: ", Style::default().fg(Theme::TEXT_DIM)),
|
||||
if state.turn_in_flight() {
|
||||
Span::styled("● Running", Style::default().fg(Theme::WARNING).add_modifier(Modifier::BOLD))
|
||||
} else {
|
||||
Span::styled("● Idle", Style::default().fg(Theme::SUCCESS))
|
||||
},
|
||||
Span::raw(" "),
|
||||
Span::styled(
|
||||
format!("Agents: {} | Findings: {}",
|
||||
state.workflow_engine.agents.len(),
|
||||
state.workflow_engine.findings.len(),
|
||||
),
|
||||
Style::default().fg(Theme::TEXT_DIM),
|
||||
),
|
||||
]));
|
||||
}
|
||||
Style::default().fg(Theme::TEXT_DIM),
|
||||
),
|
||||
]));
|
||||
|
||||
let header = Paragraph::new(header_lines);
|
||||
frame.render_widget(header, chunks[0]);
|
||||
@@ -264,7 +201,7 @@ fn build_session_lines(state: &crate::app::state::rest::AppStateRest) -> Vec<Lin
|
||||
|
||||
lines.push(Line::from(Span::raw("")));
|
||||
lines.push(Line::from(Span::styled(
|
||||
" Complex tasks auto-delegate to the company pipeline.",
|
||||
" Complex tasks auto-trigger a hive-mind convergence.",
|
||||
Style::default().fg(Theme::TEXT_DIM).add_modifier(Modifier::ITALIC),
|
||||
)));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user