Add Agent manager

Change-Id: Iaa68e9228165bd274f9c5be9d4320ef49a009ca8
diff --git a/server/assignment/auto_assignment.go b/server/assignment/auto_assignment.go
index ed01be8..a5738c0 100644
--- a/server/assignment/auto_assignment.go
+++ b/server/assignment/auto_assignment.go
@@ -56,7 +56,7 @@
 // GetAssignmentRecommendations returns ranked recommendations for task assignment
 func (a *AutoAssigner) GetAssignmentRecommendations(task *tm.Task) []AssignmentScore {
 	scores := a.calculateScores(task)
-	
+
 	// Sort by score (highest first)
 	sort.Slice(scores, func(i, j int) bool {
 		return scores[i].Score > scores[j].Score
@@ -81,13 +81,13 @@
 
 		// Score based on task type keywords
 		score.Score += a.scoreTaskTypes(agent.TaskTypes, taskKeywords, score)
-		
+
 		// Score based on capabilities
 		score.Score += a.scoreCapabilities(agent.Capabilities, taskKeywords, score)
-		
+
 		// Score based on task priority and agent model
 		score.Score += a.scorePriorityModelMatch(task.Priority, agent.Model, score)
-		
+
 		// Score based on explicit agent mention in task
 		score.Score += a.scoreExplicitMention(agent.Name, agent.Role, taskText, score)
 
@@ -100,7 +100,7 @@
 // scoreTaskTypes scores based on task type matching
 func (a *AutoAssigner) scoreTaskTypes(agentTypes []string, taskKeywords []string, score *AssignmentScore) float64 {
 	typeScore := 0.0
-	
+
 	for _, agentType := range agentTypes {
 		for _, keyword := range taskKeywords {
 			if strings.Contains(keyword, agentType) || strings.Contains(agentType, keyword) {
@@ -109,14 +109,14 @@
 			}
 		}
 	}
-	
+
 	return typeScore
 }
 
 // scoreCapabilities scores based on capability matching
 func (a *AutoAssigner) scoreCapabilities(capabilities []string, taskKeywords []string, score *AssignmentScore) float64 {
 	capScore := 0.0
-	
+
 	for _, capability := range capabilities {
 		for _, keyword := range taskKeywords {
 			if strings.Contains(keyword, capability) || strings.Contains(capability, keyword) {
@@ -125,46 +125,46 @@
 			}
 		}
 	}
-	
+
 	return capScore
 }
 
 // scorePriorityModelMatch scores based on priority and model sophistication
 func (a *AutoAssigner) scorePriorityModelMatch(priority tm.TaskPriority, model string, score *AssignmentScore) float64 {
 	priorityScore := 0.0
-	
+
 	// High priority tasks prefer more capable models
 	if priority == tm.PriorityHigh && strings.Contains(model, "gpt-4") {
 		priorityScore += 1.0
 		score.Reasons = append(score.Reasons, "high priority task matches advanced model")
 	}
-	
+
 	// Medium/low priority can use efficient models
 	if priority != tm.PriorityHigh && strings.Contains(model, "gpt-3.5") {
 		priorityScore += 0.5
 		score.Reasons = append(score.Reasons, "priority matches model efficiency")
 	}
-	
+
 	return priorityScore
 }
 
 // scoreExplicitMention scores based on explicit agent/role mentions
 func (a *AutoAssigner) scoreExplicitMention(agentName, agentRole, taskText string, score *AssignmentScore) float64 {
 	mentionScore := 0.0
-	
+
 	// Check for explicit agent name mention
 	if strings.Contains(taskText, agentName) {
 		mentionScore += 5.0
 		score.Reasons = append(score.Reasons, "explicitly mentioned by name")
 	}
-	
+
 	// Check for role mention
 	roleLower := strings.ToLower(agentRole)
 	if strings.Contains(taskText, roleLower) {
 		mentionScore += 4.0
 		score.Reasons = append(score.Reasons, "role mentioned in task")
 	}
-	
+
 	return mentionScore
 }
 
@@ -174,7 +174,7 @@
 	words := strings.FieldsFunc(text, func(c rune) bool {
 		return c == ' ' || c == ',' || c == '.' || c == ':' || c == ';' || c == '\n' || c == '\t'
 	})
-	
+
 	// Filter out common stop words and short words
 	stopWords := map[string]bool{
 		"the": true, "a": true, "an": true, "and": true, "or": true, "but": true,
@@ -183,7 +183,7 @@
 		"be": true, "been": true, "have": true, "has": true, "had": true, "do": true,
 		"does": true, "did": true, "will": true, "would": true, "could": true, "should": true,
 	}
-	
+
 	keywords := make([]string, 0)
 	for _, word := range words {
 		word = strings.ToLower(strings.TrimSpace(word))
@@ -191,7 +191,7 @@
 			keywords = append(keywords, word)
 		}
 	}
-	
+
 	return keywords
 }
 
@@ -203,7 +203,7 @@
 			return nil
 		}
 	}
-	
+
 	return fmt.Errorf("agent '%s' not found", agentName)
 }
 
@@ -214,24 +214,24 @@
 			return agent.Capabilities, nil
 		}
 	}
-	
+
 	return nil, fmt.Errorf("agent '%s' not found", agentName)
 }
 
 // GetRecommendationExplanation returns a human-readable explanation for assignment
 func (a *AutoAssigner) GetRecommendationExplanation(task *tm.Task, agentName string) string {
 	recommendations := a.GetAssignmentRecommendations(task)
-	
+
 	for _, rec := range recommendations {
 		if rec.AgentName == agentName {
 			if len(rec.Reasons) == 0 {
 				return fmt.Sprintf("Agent %s assigned (score: %.1f)", agentName, rec.Score)
 			}
-			
+
 			reasons := strings.Join(rec.Reasons, ", ")
 			return fmt.Sprintf("Agent %s assigned (score: %.1f) because: %s", agentName, rec.Score, reasons)
 		}
 	}
-	
+
 	return fmt.Sprintf("Agent %s assigned (manual override)", agentName)
-}
\ No newline at end of file
+}