picoclaw/pkg/swarm/core/core.go
Danieldd28 52e3470e06 feat: implement swarm agents with hierarchical collaboration and vector memory
This commit introduces a multi-agent Swarm Engine to PicoClaw,
enabling complex task orchestration through autonomous collaboration and long-term
semantic memory.

Key Features:
- Actor Model Architecture: Every agent (node) runs in an isolated goroutine,
  communicating via a lightweight internal Event Bus.
- Hierarchical Delegation: Manager nodes can dynamically spawn specialized
  worker nodes (Researchers, Analysts, etc.) to perform sub-tasks in parallel.
- Hybrid Memory System: Combined SQLite for state persistence and Chromem-go
  for a persistent, cross-swarm Vector Knowledge Base.
- Progressive Summarization: Implemented an intelligent memory pruning mechanism
  that summarizes older context before truncation to preserve findings without
  exceeding token limits.
- Role-Based Access Control (RBAC): Configurable tool policies per role
  (e.g., Researchers can browse but not execute shell commands).

Performance & Scaling:
- Low Footprint: Idle memory usage is ~7-8 MB RSS.
- Efficient Scaling: During a stress test with 10 concurrent agents performing
  intensive research, memory usage peaked at only 27 MB.
- Per-Node Cost: Each active agent consumes approximately 0.6 MB to 2 MB of
  physical RAM depending on conversation length and summarization state.
- Stability: Successfully handled 10 parallel LLM requests with zero race
  conditions, showcasing the robustness of the Go-based Actor model.

Integration:
- Native CLI Support: Added /swarm spawn, /swarm list, and /swarm status commands.
- Mermaid Visualization: Support for /swarm viz <id> to generate organizational
  charts of active agent hierarchies.
- Configurable: Roles, models, and security policies are fully customizable
  via config.json.
2026-02-10 21:53:43 +07:00

128 lines
3.1 KiB
Go

package core
import (
"encoding/json"
"errors"
"time"
)
// --- Common Errors ---
var (
ErrSwarmNotFound = errors.New("swarm not found")
ErrNodeNotFound = errors.New("node not found")
ErrTaskTimeout = errors.New("task timeout")
ErrMailboxFull = errors.New("mailbox full")
)
// --- ID Types ---
type SwarmID string
type NodeID string
// --- Enums ---
type SwarmStatus string
const (
SwarmStatusActive SwarmStatus = "active"
SwarmStatusPaused SwarmStatus = "paused"
SwarmStatusCompleted SwarmStatus = "completed"
)
type NodeStatus string
const (
NodeStatusPending NodeStatus = "pending"
NodeStatusRunning NodeStatus = "running"
NodeStatusCompleted NodeStatus = "completed"
NodeStatusFailed NodeStatus = "failed"
)
// --- Core Structs ---
type Swarm struct {
ID SwarmID `json:"id"`
Goal string `json:"goal"`
Status SwarmStatus `json:"status"`
CreatedAt time.Time `json:"created_at"`
}
type Node struct {
ID NodeID `json:"id"`
SwarmID SwarmID `json:"swarm_id"`
ParentID NodeID `json:"parent_id"`
Role Role `json:"role"`
Task string `json:"task"`
Status NodeStatus `json:"status"`
Output string `json:"output"`
Stats NodeStats `json:"stats"`
}
type Role struct {
Name string `json:"name"`
Description string `json:"description"`
SystemPrompt string `json:"system_prompt"`
Tools []string `json:"tools"`
Model string `json:"model"`
}
type NodeStats struct {
Iterations int `json:"iterations"`
TokensInput int `json:"tokens_input"`
TokensOutput int `json:"tokens_output"`
}
// --- Event Protocol ---
type EventType string
const (
EventNodeThinking EventType = "node.thinking"
EventNodeCompleted EventType = "node.completed"
EventNodeFailed EventType = "node.failed"
EventSwarmSpawned EventType = "swarm.spawned"
)
type Event struct {
Type EventType `json:"type"`
SwarmID SwarmID `json:"swarm_id"`
NodeID NodeID `json:"node_id"`
Payload map[string]any `json:"payload"`
}
// --- LLM Types ---
type Message struct {
Role string `json:"role"`
Content string `json:"content"`
ToolCallID string `json:"tool_call_id,omitempty"`
}
type ToolDef struct {
Name string `json:"name"`
Description string `json:"description"`
Parameters any `json:"parameters"`
}
type LLMResponse struct {
Content string `json:"content"`
ToolCalls []ToolCall `json:"tool_calls"`
Usage TokenUsage `json:"usage"`
}
type ToolCall struct {
ID string `json:"id"`
Name string `json:"name"`
Arguments json.RawMessage `json:"arguments"`
}
type TokenUsage struct {
Input int `json:"input"`
Output int `json:"output"`
}
// --- Memory Types ---
type Fact struct {
SwarmID SwarmID `json:"swarm_id"`
Content string `json:"content"`
Confidence float64 `json:"confidence"`
Source string `json:"source"`
Metadata map[string]any `json:"metadata"`
}
type FactResult struct {
Content string `json:"content"`
Score float32 `json:"score"`
}