feat(tui): add usage overlay and sidebar for displaying usage statistics and tasks
feat(tui): implement status bar with connection and turn state indicators feat(tui): create workflow panel for agent status and progress visualization feat(web): introduce web frontend interface with static file serving feat(ws): add WebSocket interface for real-time communication and session management
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
//! Complexity heuristics — determine whether a request is complex enough to
|
||||
//! warrant hive-mind orchestration.
|
||||
|
||||
/// Heuristics to determine if a request is complex enough for hive-mind.
|
||||
pub fn is_complex_request(task: &str) -> bool {
|
||||
let complexity_indicators = [
|
||||
"refactor",
|
||||
"redesign",
|
||||
"multiple files",
|
||||
"architecture",
|
||||
"migration",
|
||||
"comprehensive",
|
||||
"end-to-end",
|
||||
"full-stack",
|
||||
];
|
||||
|
||||
let task_lower = task.to_lowercase();
|
||||
complexity_indicators
|
||||
.iter()
|
||||
.any(|&indicator| task_lower.contains(indicator))
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
//! Hive-mind cycle execution — run one cycle of parallel nodes.
|
||||
//!
|
||||
//! Flow: load settings → resolve LLM credentials → for each directive,
|
||||
//! build a SubagentContext and call run_agent → collect NodeOutputs.
|
||||
|
||||
use anyhow::Result;
|
||||
use tracing::info;
|
||||
|
||||
use zesdex_domain::cms::{AppConfigRepository, SettingsRepository};
|
||||
use zesdex_domain::core::Store;
|
||||
|
||||
use crate::persistence::{JsonAppConfigRepository, JsonSettingsRepository};
|
||||
use crate::subagent::context::SubagentContext;
|
||||
use crate::subagent::division::AccessTier;
|
||||
use crate::subagent::engine::run_agent;
|
||||
use crate::tools::ToolCtx;
|
||||
use crate::workflow::hive_mind::types::{CognitiveCycle, NodeOutput};
|
||||
|
||||
/// Execute one cycle: run each node directive and collect outputs.
|
||||
///
|
||||
/// Flow:
|
||||
/// 1. Load `Settings` and `AppConfig` from the store directory.
|
||||
/// 2. Resolve provider, model, base_url, and api_key.
|
||||
/// 3. For each directive → build `SubagentContext` → `run_agent` (Full access).
|
||||
/// 4. Collect `NodeOutput` results.
|
||||
pub async fn execute_cycle(
|
||||
cycle: &CognitiveCycle,
|
||||
tool_ctx: &ToolCtx,
|
||||
) -> Result<Vec<NodeOutput>> {
|
||||
info!(
|
||||
"Executing cycle {} with {} directives",
|
||||
cycle.index,
|
||||
cycle.directives.len()
|
||||
);
|
||||
|
||||
let store = Store::new();
|
||||
let settings = JsonSettingsRepository::new()
|
||||
.load(&store.base_dir)
|
||||
.unwrap_or_default();
|
||||
let app_config = JsonAppConfigRepository::new()
|
||||
.load(&store.base_dir)
|
||||
.unwrap_or_default();
|
||||
|
||||
let (provider, model) =
|
||||
crate::subagent::provider::resolve_subagent_provider(&settings, &app_config);
|
||||
|
||||
let base_url = app_config
|
||||
.providers
|
||||
.get(&provider)
|
||||
.map(|p| p.api_base.clone())
|
||||
.unwrap_or_else(|| "https://opencode.ai/zen/v1".to_string());
|
||||
|
||||
let api_key = crate::llm::provider::resolve_api_key(&settings, &app_config);
|
||||
|
||||
let mut outputs = Vec::new();
|
||||
for (i, directive) in cycle.directives.iter().enumerate() {
|
||||
let ctx = SubagentContext::new(
|
||||
directive.clone(),
|
||||
tool_ctx.clone(),
|
||||
"full".to_string(),
|
||||
base_url.clone(),
|
||||
api_key.clone(),
|
||||
model.clone(),
|
||||
);
|
||||
|
||||
let result = run_agent(ctx, directive, AccessTier::Full, tool_ctx.clone()).await?;
|
||||
|
||||
outputs.push(NodeOutput {
|
||||
id: format!("Node-{}-{}", cycle.index, i),
|
||||
directive: directive.clone(),
|
||||
output: result,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(outputs)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
//! Hive-mind live tracking — track running node statuses in real time.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Mutex;
|
||||
|
||||
/// Real-time status of all running hive-mind nodes.
|
||||
pub struct LiveHiveMind {
|
||||
nodes: Mutex<HashMap<String, String>>,
|
||||
}
|
||||
|
||||
impl LiveHiveMind {
|
||||
pub fn new() -> Self {
|
||||
LiveHiveMind {
|
||||
nodes: Mutex::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_status(&self, agent_id: &str, status: &str) {
|
||||
if let Ok(mut guard) = self.nodes.lock() {
|
||||
guard.insert(agent_id.to_string(), status.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_statuses(&self) -> HashMap<String, String> {
|
||||
self.nodes.lock().map(|g| g.clone()).unwrap_or_default()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
//! Hive-mind orchestration — multi-agent parallel convergence cycles.
|
||||
|
||||
pub mod complexity;
|
||||
pub mod cycle;
|
||||
pub mod live;
|
||||
pub mod synthesis;
|
||||
pub mod types;
|
||||
@@ -0,0 +1,38 @@
|
||||
//! Consensus synthesis — reconciles multiple node outputs into one assessment.
|
||||
|
||||
use anyhow::Result;
|
||||
use tracing::info;
|
||||
|
||||
use crate::tools::ToolCtx;
|
||||
use crate::workflow::hive_mind::types::NodeOutput;
|
||||
|
||||
/// Synthesize a consensus from all node outputs.
|
||||
///
|
||||
/// Flow: combine node outputs → return consensus text.
|
||||
/// Uses simple concatenation-based synthesis (avoids LLM call dependency).
|
||||
pub async fn synthesize_consensus(
|
||||
nodes: &[NodeOutput],
|
||||
_tool_ctx: &ToolCtx,
|
||||
) -> Result<String> {
|
||||
info!("Synthesizing consensus from {} nodes", nodes.len());
|
||||
|
||||
let mut combined = String::new();
|
||||
for node in nodes {
|
||||
combined.push_str(&format!(
|
||||
"\n## {} — {}\n\n{}\n",
|
||||
node.id, node.directive, node.output
|
||||
));
|
||||
}
|
||||
|
||||
Ok(format!(
|
||||
"# Consensus Synthesis\n\
|
||||
Nodes synthesized: {}\n\n\
|
||||
## Summary\n\
|
||||
The following node outputs were collected:\n\
|
||||
{}\n\n\
|
||||
## Key Findings\n\
|
||||
Review the individual node outputs above for detailed findings.",
|
||||
nodes.len(),
|
||||
combined
|
||||
))
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
//! Hive-mind shared types — node directives, cycle plans, and node outputs.
|
||||
|
||||
/// A directive for a single processing node in the hive mind.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NodeDirective {
|
||||
pub directive: String,
|
||||
pub access_tier: String,
|
||||
}
|
||||
|
||||
/// A cognitive cycle plan — ordered list of cycles, each containing
|
||||
/// parallel node directives.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CognitiveCyclePlan {
|
||||
pub cycles: Vec<Vec<NodeDirective>>,
|
||||
}
|
||||
|
||||
/// A single cycle in a cognitive cycle plan — parallel node directives
|
||||
/// executed together.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CognitiveCycle {
|
||||
pub index: u32,
|
||||
pub directives: Vec<String>,
|
||||
}
|
||||
|
||||
/// Output from a single hive-mind processing node after a cycle completes.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NodeOutput {
|
||||
pub id: String,
|
||||
pub directive: String,
|
||||
pub output: String,
|
||||
}
|
||||
Reference in New Issue
Block a user