From 5bfea8687a94a7526c4d02420ad035e9c6b7bd40 Mon Sep 17 00:00:00 2001 From: Danieldd28 Date: Wed, 11 Feb 2026 01:08:59 +0700 Subject: [PATCH] feat: complete swarm engine implementation 1. Implemented missing /swarm status and /swarm viz commands. 2. Made DelegateTool roles dynamic based on configuration. 3. Aligned codebase with README documentation. --- pkg/swarm/runtime/delegation.go | 12 ++++++++++-- pkg/swarm/service.go | 30 +++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/pkg/swarm/runtime/delegation.go b/pkg/swarm/runtime/delegation.go index 0627be556..67043284f 100644 --- a/pkg/swarm/runtime/delegation.go +++ b/pkg/swarm/runtime/delegation.go @@ -31,13 +31,21 @@ func (t *DelegateTool) Description() string { } func (t *DelegateTool) Parameters() map[string]interface{} { + roles := make([]string, 0) + for roleName := range t.orchestrator.config.Roles { + roles = append(roles, roleName) + } + if len(roles) == 0 { + roles = []string{"Researcher", "Analyst", "Writer", "Critic"} // Fallback + } + return map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "role": map[string]interface{}{ "type": "string", - "description": "The role of the worker (Researcher, Analyst, Writer, Critic)", - "enum": []string{"Researcher", "Analyst", "Writer", "Critic"}, + "description": "The role of the worker to spawn", + "enum": roles, }, "task": map[string]interface{}{ "type": "string", diff --git a/pkg/swarm/service.go b/pkg/swarm/service.go index 0c7589526..80d75ee02 100644 --- a/pkg/swarm/service.go +++ b/pkg/swarm/service.go @@ -58,7 +58,7 @@ func (s *Service) listen() { func (s *Service) HandleCommand(ctx context.Context, input string) string { args := strings.Fields(input) - if len(args) < 2 { return "Usage: /swarm [goal]" } + if len(args) < 2 { return "Usage: /swarm [goal/id]" } switch args[1] { case "spawn": @@ -80,6 +80,34 @@ func (s *Service) HandleCommand(ctx context.Context, input string) string { if len(args) < 3 { return "ID required" } s.Orchestrator.StopSwarm(core.SwarmID(args[2])) return "Stopped." + case "status": + if len(args) < 3 { return "ID required" } + sid := core.SwarmID(args[2]) + sw, err := s.Store.GetSwarm(ctx, sid) + if err != nil { return "Swarm not found" } + nodes, _ := s.Store.GetSwarmNodes(ctx, sid) + + out := fmt.Sprintf("📊 Swarm Status: %s\nGoal: %s\nNodes (%d):\n", sw.Status, sw.Goal, len(nodes)) + for _, n := range nodes { + out += fmt.Sprintf("- [%s] %s: %s (%s)\n", n.ID[:4], n.Role.Name, n.Status, n.Task) + } + return out + case "viz": + if len(args) < 3 { return "ID required" } + sid := core.SwarmID(args[2]) + nodes, _ := s.Store.GetSwarmNodes(ctx, sid) + if len(nodes) == 0 { return "No nodes found" } + + out := "```mermaid\ngraph TD\n" + for _, n := range nodes { + nodeLabel := fmt.Sprintf("%s[%s: %s]", n.ID[:8], n.Role.Name, n.Status) + out += fmt.Sprintf(" %s\n", nodeLabel) + if n.ParentID != "" { + out += fmt.Sprintf(" %s --> %s\n", n.ParentID[:8], n.ID[:8]) + } + } + out += "```" + return out } return "Unknown command" }