Full Cargo workspace with 11 crates: - gyandoot-core: Shared types, config, error types - gyandoot-agent: Agent loop, tool execution, context compression - gyandoot-providers: LLM provider abstraction (OpenAI, Anthropic, Ollama) - gyandoot-memory: MemPalace persistent memory system - gyandoot-platform: Platform adapters (Telegram, Discord, Webhook, CLI) - gyandoot-security: Credential vault, sanitizer, threat detector - gyandoot-kanban: Task decomposition, swarm orchestration, diagnostics - gyandoot-subagents: Sub-agent spawning and orchestration - gyandoot-skills: Skills discovery, loading, preprocessing, bundles - gyandoot-profile: Multi-agent profile manager - gyandoot-gateway: Gateway sessions, routing, access control Plus: CLI entry point with clap, cross-platform installer script, KANBAN.md, .gnpl/AGENTS.md Workspace compiles clean: cargo check passes with 0 errors.
127 lines
3.5 KiB
Rust
127 lines
3.5 KiB
Rust
//! GyanDoot Kanban — Task decomposition, swarm execution, and diagnostics.
|
|
//!
|
|
//! The Kanban system manages tasks from decomposition into subtasks,
|
|
//! parallel execution via a swarm of sub-agents, and diagnostics
|
|
//! for tracking progress and bottlenecks.
|
|
|
|
use gyandoot_core::{KanbanResult, Priority, Task, TaskStatus};
|
|
use uuid::Uuid;
|
|
|
|
pub mod decompose;
|
|
pub mod swarm;
|
|
pub mod diagnostics;
|
|
|
|
pub use decompose::Decomposer;
|
|
pub use swarm::Swarm;
|
|
pub use diagnostics::Diagnostics;
|
|
|
|
/// The central Kanban board managing all tasks.
|
|
pub struct KanbanBoard {
|
|
tasks: Vec<Task>,
|
|
decomposer: decompose::Decomposer,
|
|
swarm: swarm::Swarm,
|
|
diagnostics: diagnostics::Diagnostics,
|
|
}
|
|
|
|
impl KanbanBoard {
|
|
/// Create a new empty Kanban board.
|
|
pub fn new() -> Self {
|
|
Self {
|
|
tasks: Vec::new(),
|
|
decomposer: decompose::Decomposer::new(),
|
|
swarm: swarm::Swarm::new(),
|
|
diagnostics: diagnostics::Diagnostics::new(),
|
|
}
|
|
}
|
|
|
|
/// Add a task to the board.
|
|
pub fn add_task(&mut self, title: String, description: String, priority: Priority) -> Task {
|
|
let task = Task {
|
|
id: Uuid::new_v4(),
|
|
title,
|
|
description,
|
|
priority,
|
|
status: TaskStatus::Backlog,
|
|
assigned_agent: None,
|
|
created_at: chrono::Utc::now(),
|
|
updated_at: chrono::Utc::now(),
|
|
subtasks: Vec::new(),
|
|
dependencies: Vec::new(),
|
|
tags: Vec::new(),
|
|
};
|
|
self.tasks.push(task.clone());
|
|
task
|
|
}
|
|
|
|
/// Get a task by ID.
|
|
pub fn get_task(&self, id: &Uuid) -> Option<&Task> {
|
|
self.tasks.iter().find(|t| t.id == *id)
|
|
}
|
|
|
|
/// Update the status of a task.
|
|
pub fn update_status(&mut self, id: &Uuid, status: TaskStatus) -> KanbanResult<()> {
|
|
let task = self
|
|
.tasks
|
|
.iter_mut()
|
|
.find(|t| t.id == *id)
|
|
.ok_or_else(|| gyandoot_core::KanbanError::TaskNotFound(id.to_string()))?;
|
|
task.status = status;
|
|
task.updated_at = chrono::Utc::now();
|
|
Ok(())
|
|
}
|
|
|
|
/// List all tasks with a given status.
|
|
pub fn tasks_by_status(&self, status: TaskStatus) -> Vec<&Task> {
|
|
self.tasks.iter().filter(|t| t.status == status).collect()
|
|
}
|
|
|
|
/// Get a reference to the decomposer.
|
|
pub fn decomposer(&self) -> &decompose::Decomposer {
|
|
&self.decomposer
|
|
}
|
|
|
|
/// Get a mutable reference to the decomposer.
|
|
pub fn decomposer_mut(&mut self) -> &mut decompose::Decomposer {
|
|
&mut self.decomposer
|
|
}
|
|
|
|
/// Get a reference to the swarm.
|
|
pub fn swarm(&self) -> &swarm::Swarm {
|
|
&self.swarm
|
|
}
|
|
|
|
/// Get a mutable reference to the swarm.
|
|
pub fn swarm_mut(&mut self) -> &mut swarm::Swarm {
|
|
&mut self.swarm
|
|
}
|
|
|
|
/// Get a reference to the diagnostics.
|
|
pub fn diagnostics(&self) -> &diagnostics::Diagnostics {
|
|
&self.diagnostics
|
|
}
|
|
}
|
|
|
|
impl Default for KanbanBoard {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_board_lifecycle() {
|
|
let mut board = KanbanBoard::new();
|
|
let task = board.add_task(
|
|
"Write tests".to_string(),
|
|
"Add unit tests for the agent loop".to_string(),
|
|
Priority::High,
|
|
);
|
|
assert_eq!(task.status, TaskStatus::Backlog);
|
|
|
|
board.update_status(&task.id, TaskStatus::InProgress).unwrap();
|
|
assert_eq!(board.get_task(&task.id).unwrap().status, TaskStatus::InProgress);
|
|
}
|
|
} |