WIP: Save agent roles integration work before CHORUS rebrand
- Agent roles and coordination features - Chat API integration testing - New configuration and workspace management 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
495
agent/role_config.go
Normal file
495
agent/role_config.go
Normal file
@@ -0,0 +1,495 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// AgentRole represents different agent roles in the system
|
||||
type AgentRole string
|
||||
|
||||
const (
|
||||
BackendRole AgentRole = "backend"
|
||||
FrontendRole AgentRole = "frontend"
|
||||
DevOpsRole AgentRole = "devops"
|
||||
QARole AgentRole = "qa"
|
||||
TestingRole AgentRole = "testing"
|
||||
GeneralRole AgentRole = "general"
|
||||
)
|
||||
|
||||
// RoleCapability represents capabilities of an agent role
|
||||
type RoleCapability struct {
|
||||
Name string
|
||||
Description string
|
||||
Weight float64
|
||||
}
|
||||
|
||||
// DirectoryScope represents directory patterns for context filtering
|
||||
type DirectoryScope struct {
|
||||
Patterns []string
|
||||
Description string
|
||||
}
|
||||
|
||||
// RoleConfig holds configuration for an agent role
|
||||
type RoleConfig struct {
|
||||
Role AgentRole
|
||||
DisplayName string
|
||||
Description string
|
||||
Capabilities []RoleCapability
|
||||
DirectoryScopes DirectoryScope
|
||||
TaskTypes []string
|
||||
Priority int
|
||||
|
||||
// Context filtering parameters
|
||||
ContextWeight float64
|
||||
FeedbackWeight float64
|
||||
LearningRate float64
|
||||
}
|
||||
|
||||
// RoleManager manages agent roles and their configurations
|
||||
type RoleManager struct {
|
||||
roles map[AgentRole]*RoleConfig
|
||||
agentRoles map[string]AgentRole // Maps agent ID to role
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
// NewRoleManager creates a new role manager with default configurations
|
||||
func NewRoleManager() *RoleManager {
|
||||
rm := &RoleManager{
|
||||
roles: make(map[AgentRole]*RoleConfig),
|
||||
agentRoles: make(map[string]AgentRole),
|
||||
}
|
||||
|
||||
rm.initializeDefaultRoles()
|
||||
return rm
|
||||
}
|
||||
|
||||
// initializeDefaultRoles sets up default role configurations
|
||||
func (rm *RoleManager) initializeDefaultRoles() {
|
||||
// Backend role configuration
|
||||
rm.roles[BackendRole] = &RoleConfig{
|
||||
Role: BackendRole,
|
||||
DisplayName: "Backend Developer",
|
||||
Description: "Specializes in server-side development, APIs, databases, and backend services",
|
||||
Capabilities: []RoleCapability{
|
||||
{Name: "api_development", Description: "REST/GraphQL API development", Weight: 1.0},
|
||||
{Name: "database_design", Description: "Database schema and query optimization", Weight: 0.9},
|
||||
{Name: "server_architecture", Description: "Server architecture and microservices", Weight: 0.9},
|
||||
{Name: "authentication", Description: "Authentication and authorization systems", Weight: 0.8},
|
||||
{Name: "caching", Description: "Caching strategies and implementation", Weight: 0.8},
|
||||
},
|
||||
DirectoryScopes: DirectoryScope{
|
||||
Patterns: []string{
|
||||
"*/backend/*",
|
||||
"*/api/*",
|
||||
"*/services/*",
|
||||
"*/server/*",
|
||||
"*/core/*",
|
||||
"*/models/*",
|
||||
"*/controllers/*",
|
||||
"*/middleware/*",
|
||||
},
|
||||
Description: "Backend-related directories and server-side code",
|
||||
},
|
||||
TaskTypes: []string{
|
||||
"api_development",
|
||||
"database_migration",
|
||||
"backend_optimization",
|
||||
"server_configuration",
|
||||
"authentication_setup",
|
||||
},
|
||||
Priority: 5,
|
||||
ContextWeight: 1.0,
|
||||
FeedbackWeight: 0.3,
|
||||
LearningRate: 0.1,
|
||||
}
|
||||
|
||||
// Frontend role configuration
|
||||
rm.roles[FrontendRole] = &RoleConfig{
|
||||
Role: FrontendRole,
|
||||
DisplayName: "Frontend Developer",
|
||||
Description: "Specializes in user interfaces, client-side logic, and user experience",
|
||||
Capabilities: []RoleCapability{
|
||||
{Name: "ui_development", Description: "User interface development", Weight: 1.0},
|
||||
{Name: "responsive_design", Description: "Responsive and mobile-first design", Weight: 0.9},
|
||||
{Name: "state_management", Description: "Client-side state management", Weight: 0.8},
|
||||
{Name: "component_architecture", Description: "Component-based architecture", Weight: 0.9},
|
||||
{Name: "accessibility", Description: "Web accessibility implementation", Weight: 0.7},
|
||||
},
|
||||
DirectoryScopes: DirectoryScope{
|
||||
Patterns: []string{
|
||||
"*/frontend/*",
|
||||
"*/ui/*",
|
||||
"*/client/*",
|
||||
"*/web/*",
|
||||
"*/components/*",
|
||||
"*/pages/*",
|
||||
"*/styles/*",
|
||||
"*/assets/*",
|
||||
},
|
||||
Description: "Frontend-related directories and client-side code",
|
||||
},
|
||||
TaskTypes: []string{
|
||||
"ui_implementation",
|
||||
"component_development",
|
||||
"responsive_design",
|
||||
"frontend_optimization",
|
||||
"user_experience",
|
||||
},
|
||||
Priority: 4,
|
||||
ContextWeight: 0.8,
|
||||
FeedbackWeight: 0.3,
|
||||
LearningRate: 0.1,
|
||||
}
|
||||
|
||||
// DevOps role configuration
|
||||
rm.roles[DevOpsRole] = &RoleConfig{
|
||||
Role: DevOpsRole,
|
||||
DisplayName: "DevOps Engineer",
|
||||
Description: "Specializes in deployment, infrastructure, CI/CD, and system operations",
|
||||
Capabilities: []RoleCapability{
|
||||
{Name: "infrastructure", Description: "Infrastructure as Code", Weight: 1.0},
|
||||
{Name: "containerization", Description: "Docker and container orchestration", Weight: 0.9},
|
||||
{Name: "ci_cd", Description: "Continuous Integration/Deployment", Weight: 0.9},
|
||||
{Name: "monitoring", Description: "System monitoring and alerting", Weight: 0.8},
|
||||
{Name: "security", Description: "Security and compliance", Weight: 0.8},
|
||||
},
|
||||
DirectoryScopes: DirectoryScope{
|
||||
Patterns: []string{
|
||||
"*/deploy/*",
|
||||
"*/config/*",
|
||||
"*/docker/*",
|
||||
"*/k8s/*",
|
||||
"*/kubernetes/*",
|
||||
"*/infrastructure/*",
|
||||
"*/scripts/*",
|
||||
"*/ci/*",
|
||||
"*.yml",
|
||||
"*.yaml",
|
||||
"Dockerfile*",
|
||||
"docker-compose*",
|
||||
},
|
||||
Description: "DevOps-related configuration and deployment files",
|
||||
},
|
||||
TaskTypes: []string{
|
||||
"deployment",
|
||||
"infrastructure_setup",
|
||||
"ci_cd_pipeline",
|
||||
"system_monitoring",
|
||||
"security_configuration",
|
||||
},
|
||||
Priority: 5,
|
||||
ContextWeight: 1.0,
|
||||
FeedbackWeight: 0.4,
|
||||
LearningRate: 0.1,
|
||||
}
|
||||
|
||||
// QA role configuration
|
||||
rm.roles[QARole] = &RoleConfig{
|
||||
Role: QARole,
|
||||
DisplayName: "Quality Assurance",
|
||||
Description: "Specializes in quality assurance, code review, and process improvement",
|
||||
Capabilities: []RoleCapability{
|
||||
{Name: "code_review", Description: "Code review and quality assessment", Weight: 1.0},
|
||||
{Name: "process_improvement", Description: "Development process improvement", Weight: 0.9},
|
||||
{Name: "quality_metrics", Description: "Quality metrics and reporting", Weight: 0.8},
|
||||
{Name: "best_practices", Description: "Best practices enforcement", Weight: 0.9},
|
||||
{Name: "documentation", Description: "Documentation quality assurance", Weight: 0.7},
|
||||
},
|
||||
DirectoryScopes: DirectoryScope{
|
||||
Patterns: []string{
|
||||
"*/tests/*",
|
||||
"*/quality/*",
|
||||
"*/review/*",
|
||||
"*/docs/*",
|
||||
"*/documentation/*",
|
||||
"*", // QA role gets broader access for review purposes
|
||||
},
|
||||
Description: "All directories for quality assurance and code review",
|
||||
},
|
||||
TaskTypes: []string{
|
||||
"code_review",
|
||||
"quality_assessment",
|
||||
"process_improvement",
|
||||
"documentation_review",
|
||||
"compliance_check",
|
||||
},
|
||||
Priority: 4,
|
||||
ContextWeight: 0.7,
|
||||
FeedbackWeight: 0.5,
|
||||
LearningRate: 0.2,
|
||||
}
|
||||
|
||||
// Testing role configuration
|
||||
rm.roles[TestingRole] = &RoleConfig{
|
||||
Role: TestingRole,
|
||||
DisplayName: "Test Engineer",
|
||||
Description: "Specializes in automated testing, test frameworks, and test strategy",
|
||||
Capabilities: []RoleCapability{
|
||||
{Name: "unit_testing", Description: "Unit test development", Weight: 1.0},
|
||||
{Name: "integration_testing", Description: "Integration test development", Weight: 0.9},
|
||||
{Name: "e2e_testing", Description: "End-to-end test automation", Weight: 0.9},
|
||||
{Name: "test_frameworks", Description: "Test framework setup and maintenance", Weight: 0.8},
|
||||
{Name: "performance_testing", Description: "Performance and load testing", Weight: 0.7},
|
||||
},
|
||||
DirectoryScopes: DirectoryScope{
|
||||
Patterns: []string{
|
||||
"*/tests/*",
|
||||
"*/spec/*",
|
||||
"*/test/*",
|
||||
"*/e2e/*",
|
||||
"*/integration/*",
|
||||
"*/__tests__/*",
|
||||
"*.test.*",
|
||||
"*.spec.*",
|
||||
},
|
||||
Description: "Test-related directories and files",
|
||||
},
|
||||
TaskTypes: []string{
|
||||
"unit_testing",
|
||||
"integration_testing",
|
||||
"e2e_testing",
|
||||
"test_automation",
|
||||
"performance_testing",
|
||||
},
|
||||
Priority: 4,
|
||||
ContextWeight: 0.6,
|
||||
FeedbackWeight: 0.4,
|
||||
LearningRate: 0.15,
|
||||
}
|
||||
|
||||
// General role configuration
|
||||
rm.roles[GeneralRole] = &RoleConfig{
|
||||
Role: GeneralRole,
|
||||
DisplayName: "General Developer",
|
||||
Description: "General-purpose development with broad capabilities",
|
||||
Capabilities: []RoleCapability{
|
||||
{Name: "general_development", Description: "General software development", Weight: 0.7},
|
||||
{Name: "problem_solving", Description: "General problem solving", Weight: 0.8},
|
||||
{Name: "documentation", Description: "Documentation writing", Weight: 0.6},
|
||||
{Name: "code_maintenance", Description: "Code maintenance and refactoring", Weight: 0.7},
|
||||
{Name: "research", Description: "Technical research and analysis", Weight: 0.8},
|
||||
},
|
||||
DirectoryScopes: DirectoryScope{
|
||||
Patterns: []string{
|
||||
"*", // General role has access to all directories
|
||||
},
|
||||
Description: "All directories for general development tasks",
|
||||
},
|
||||
TaskTypes: []string{
|
||||
"general_development",
|
||||
"documentation",
|
||||
"code_maintenance",
|
||||
"research",
|
||||
"bug_fixes",
|
||||
},
|
||||
Priority: 2,
|
||||
ContextWeight: 0.5,
|
||||
FeedbackWeight: 0.2,
|
||||
LearningRate: 0.1,
|
||||
}
|
||||
}
|
||||
|
||||
// AssignRole assigns a role to an agent
|
||||
func (rm *RoleManager) AssignRole(agentID string, role AgentRole) error {
|
||||
rm.mu.Lock()
|
||||
defer rm.mu.Unlock()
|
||||
|
||||
if _, exists := rm.roles[role]; !exists {
|
||||
return fmt.Errorf("role %s does not exist", role)
|
||||
}
|
||||
|
||||
rm.agentRoles[agentID] = role
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAgentRole returns the role assigned to an agent
|
||||
func (rm *RoleManager) GetAgentRole(agentID string) (AgentRole, bool) {
|
||||
rm.mu.RLock()
|
||||
defer rm.mu.RUnlock()
|
||||
|
||||
role, exists := rm.agentRoles[agentID]
|
||||
return role, exists
|
||||
}
|
||||
|
||||
// GetRoleConfig returns the configuration for a specific role
|
||||
func (rm *RoleManager) GetRoleConfig(role AgentRole) (*RoleConfig, bool) {
|
||||
rm.mu.RLock()
|
||||
defer rm.mu.RUnlock()
|
||||
|
||||
config, exists := rm.roles[role]
|
||||
return config, exists
|
||||
}
|
||||
|
||||
// GetAllRoles returns all available roles
|
||||
func (rm *RoleManager) GetAllRoles() map[AgentRole]*RoleConfig {
|
||||
rm.mu.RLock()
|
||||
defer rm.mu.RUnlock()
|
||||
|
||||
result := make(map[AgentRole]*RoleConfig)
|
||||
for role, config := range rm.roles {
|
||||
// Create a copy to avoid race conditions
|
||||
configCopy := *config
|
||||
result[role] = &configCopy
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// MatchesDirectoryScope checks if a directory path matches the agent's scope
|
||||
func (rm *RoleManager) MatchesDirectoryScope(agentID, directory string) bool {
|
||||
role, exists := rm.GetAgentRole(agentID)
|
||||
if !exists {
|
||||
return false
|
||||
}
|
||||
|
||||
config, exists := rm.GetRoleConfig(role)
|
||||
if !exists {
|
||||
return false
|
||||
}
|
||||
|
||||
return rm.matchesPatterns(directory, config.DirectoryScopes.Patterns)
|
||||
}
|
||||
|
||||
// GetRelevanceScore calculates context relevance score for an agent and directory
|
||||
func (rm *RoleManager) GetRelevanceScore(agentID, directory string) float64 {
|
||||
role, exists := rm.GetAgentRole(agentID)
|
||||
if !exists {
|
||||
return 0.1 // Low default score
|
||||
}
|
||||
|
||||
config, exists := rm.GetRoleConfig(role)
|
||||
if !exists {
|
||||
return 0.1
|
||||
}
|
||||
|
||||
if rm.matchesPatterns(directory, config.DirectoryScopes.Patterns) {
|
||||
return config.ContextWeight
|
||||
}
|
||||
|
||||
return 0.1 // Low score for non-matching directories
|
||||
}
|
||||
|
||||
// matchesPatterns checks if a directory matches any of the given patterns
|
||||
func (rm *RoleManager) matchesPatterns(directory string, patterns []string) bool {
|
||||
if directory == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
directory = strings.ToLower(directory)
|
||||
|
||||
for _, pattern := range patterns {
|
||||
pattern = strings.ToLower(pattern)
|
||||
|
||||
// Handle wildcard patterns
|
||||
if pattern == "*" {
|
||||
return true
|
||||
}
|
||||
|
||||
// Handle glob-style patterns
|
||||
if matched, _ := filepath.Match(pattern, directory); matched {
|
||||
return true
|
||||
}
|
||||
|
||||
// Handle substring matching for directory paths
|
||||
if strings.Contains(directory, strings.Trim(pattern, "*")) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// UpdateRoleWeight updates the context weight for a role (for RL learning)
|
||||
func (rm *RoleManager) UpdateRoleWeight(role AgentRole, newWeight float64) error {
|
||||
rm.mu.Lock()
|
||||
defer rm.mu.Unlock()
|
||||
|
||||
config, exists := rm.roles[role]
|
||||
if !exists {
|
||||
return fmt.Errorf("role %s does not exist", role)
|
||||
}
|
||||
|
||||
// Clamp weight to reasonable bounds
|
||||
if newWeight < 0.1 {
|
||||
newWeight = 0.1
|
||||
}
|
||||
if newWeight > 2.0 {
|
||||
newWeight = 2.0
|
||||
}
|
||||
|
||||
config.ContextWeight = newWeight
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAgentsByRole returns all agents assigned to a specific role
|
||||
func (rm *RoleManager) GetAgentsByRole(role AgentRole) []string {
|
||||
rm.mu.RLock()
|
||||
defer rm.mu.RUnlock()
|
||||
|
||||
var agents []string
|
||||
for agentID, agentRole := range rm.agentRoles {
|
||||
if agentRole == role {
|
||||
agents = append(agents, agentID)
|
||||
}
|
||||
}
|
||||
return agents
|
||||
}
|
||||
|
||||
// GetCapabilitiesForRole returns capabilities for a specific role
|
||||
func (rm *RoleManager) GetCapabilitiesForRole(role AgentRole) ([]RoleCapability, bool) {
|
||||
config, exists := rm.GetRoleConfig(role)
|
||||
if !exists {
|
||||
return nil, false
|
||||
}
|
||||
return config.Capabilities, true
|
||||
}
|
||||
|
||||
// CanHandleTaskType checks if a role can handle a specific task type
|
||||
func (rm *RoleManager) CanHandleTaskType(role AgentRole, taskType string) bool {
|
||||
config, exists := rm.GetRoleConfig(role)
|
||||
if !exists {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, supportedType := range config.TaskTypes {
|
||||
if supportedType == taskType {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// GetBestRoleForDirectory returns the best role for a given directory
|
||||
func (rm *RoleManager) GetBestRoleForDirectory(directory string) (AgentRole, float64) {
|
||||
bestRole := GeneralRole
|
||||
bestScore := 0.0
|
||||
|
||||
for role, config := range rm.roles {
|
||||
if rm.matchesPatterns(directory, config.DirectoryScopes.Patterns) {
|
||||
score := config.ContextWeight * float64(config.Priority) / 5.0
|
||||
if score > bestScore {
|
||||
bestScore = score
|
||||
bestRole = role
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bestRole, bestScore
|
||||
}
|
||||
|
||||
// String returns string representation of AgentRole
|
||||
func (ar AgentRole) String() string {
|
||||
return string(ar)
|
||||
}
|
||||
|
||||
// IsValid checks if the agent role is valid
|
||||
func (ar AgentRole) IsValid() bool {
|
||||
switch ar {
|
||||
case BackendRole, FrontendRole, DevOpsRole, QARole, TestingRole, GeneralRole:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user