diff --git a/server/agent/manager.go b/server/agent/manager.go
new file mode 100644
index 0000000..2d31b87
--- /dev/null
+++ b/server/agent/manager.go
@@ -0,0 +1,583 @@
+package agent
+
+import (
+	"context"
+	"fmt"
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+	"time"
+
+	"github.com/iomodo/staff/assignment"
+	"github.com/iomodo/staff/config"
+	"github.com/iomodo/staff/git"
+	"github.com/iomodo/staff/llm"
+	_ "github.com/iomodo/staff/llm/providers" // Auto-register all providers
+	"github.com/iomodo/staff/tm"
+)
+
+// Manager manages multiple AI agents with Git operations and task processing
+type Manager struct {
+	config       *config.Config
+	agents       map[string]*Agent
+	taskManager  tm.TaskManager
+	autoAssigner *assignment.AutoAssigner
+	prProvider   git.PullRequestProvider
+	cloneManager *git.CloneManager
+	isRunning    map[string]bool
+	stopChannels map[string]chan struct{}
+}
+
+// NewManager creates a new agent manager
+func NewManager(cfg *config.Config, taskManager tm.TaskManager) (*Manager, error) {
+	// Create auto-assigner
+	autoAssigner := assignment.NewAutoAssigner(cfg.Agents)
+
+	// Create GitHub PR provider
+	githubConfig := git.GitHubConfig{
+		Token: cfg.GitHub.Token,
+	}
+	prProvider := git.NewGitHubPullRequestProvider(cfg.GitHub.Owner, cfg.GitHub.Repo, githubConfig)
+
+	// Create clone manager for per-agent Git repositories
+	repoURL := fmt.Sprintf("https://github.com/%s/%s.git", cfg.GitHub.Owner, cfg.GitHub.Repo)
+	workspacePath := filepath.Join(".", "workspace")
+	cloneManager := git.NewCloneManager(repoURL, workspacePath)
+
+	manager := &Manager{
+		config:       cfg,
+		agents:       make(map[string]*Agent),
+		taskManager:  taskManager,
+		autoAssigner: autoAssigner,
+		prProvider:   prProvider,
+		cloneManager: cloneManager,
+		isRunning:    make(map[string]bool),
+		stopChannels: make(map[string]chan struct{}),
+	}
+
+	// Initialize agents
+	if err := manager.initializeAgents(); err != nil {
+		return nil, fmt.Errorf("failed to initialize agents: %w", err)
+	}
+
+	return manager, nil
+}
+
+// initializeAgents creates agent instances from configuration
+func (m *Manager) initializeAgents() error {
+	for _, agentConfig := range m.config.Agents {
+		agent, err := m.createAgent(agentConfig)
+		if err != nil {
+			return fmt.Errorf("failed to create agent %s: %w", agentConfig.Name, err)
+		}
+		m.agents[agentConfig.Name] = agent
+	}
+	return nil
+}
+
+// createAgent creates a single agent instance
+func (m *Manager) createAgent(agentConfig config.AgentConfig) (*Agent, error) {
+	// Load system prompt
+	systemPrompt, err := m.loadSystemPrompt(agentConfig.SystemPromptFile)
+	if err != nil {
+		return nil, fmt.Errorf("failed to load system prompt: %w", err)
+	}
+
+	// Create LLM provider
+	llmConfig := llm.Config{
+		Provider: llm.ProviderOpenAI,
+		APIKey:   m.config.OpenAI.APIKey,
+		BaseURL:  m.config.OpenAI.BaseURL,
+		Timeout:  m.config.OpenAI.Timeout,
+	}
+
+	provider, err := llm.CreateProvider(llmConfig)
+	if err != nil {
+		return nil, fmt.Errorf("failed to create LLM provider: %w", err)
+	}
+
+	agent := &Agent{
+		Name:         agentConfig.Name,
+		Role:         agentConfig.Role,
+		Model:        agentConfig.Model,
+		SystemPrompt: systemPrompt,
+		Provider:     provider,
+		MaxTokens:    agentConfig.MaxTokens,
+		Temperature:  agentConfig.Temperature,
+		Stats:        AgentStats{},
+	}
+
+	return agent, nil
+}
+
+// loadSystemPrompt loads the system prompt from file
+func (m *Manager) loadSystemPrompt(filePath string) (string, error) {
+	content, err := os.ReadFile(filePath)
+	if err != nil {
+		return "", fmt.Errorf("failed to read system prompt file %s: %w", filePath, err)
+	}
+	return string(content), nil
+}
+
+// StartAgent starts an agent to process tasks in a loop
+func (m *Manager) StartAgent(agentName string, loopInterval time.Duration) error {
+	agent, exists := m.agents[agentName]
+	if !exists {
+		return fmt.Errorf("agent %s not found", agentName)
+	}
+
+	if m.isRunning[agentName] {
+		return fmt.Errorf("agent %s is already running", agentName)
+	}
+
+	stopChan := make(chan struct{})
+	m.stopChannels[agentName] = stopChan
+	m.isRunning[agentName] = true
+
+	go m.runAgentLoop(agent, loopInterval, stopChan)
+
+	log.Printf("Started agent %s (%s) with %s model", agentName, agent.Role, agent.Model)
+	return nil
+}
+
+// StopAgent stops a running agent
+func (m *Manager) StopAgent(agentName string) error {
+	if !m.isRunning[agentName] {
+		return fmt.Errorf("agent %s is not running", agentName)
+	}
+
+	close(m.stopChannels[agentName])
+	delete(m.stopChannels, agentName)
+	m.isRunning[agentName] = false
+
+	log.Printf("Stopped agent %s", agentName)
+	return nil
+}
+
+// runAgentLoop runs the main processing loop for an agent
+func (m *Manager) runAgentLoop(agent *Agent, interval time.Duration, stopChan <-chan struct{}) {
+	ticker := time.NewTicker(interval)
+	defer ticker.Stop()
+
+	for {
+		select {
+		case <-stopChan:
+			log.Printf("Agent %s stopping", agent.Name)
+			return
+		case <-ticker.C:
+			if err := m.processAgentTasks(agent); err != nil {
+				log.Printf("Error processing tasks for agent %s: %v", agent.Name, err)
+			}
+		}
+	}
+}
+
+// processAgentTasks processes all assigned tasks for an agent
+func (m *Manager) processAgentTasks(agent *Agent) error {
+	if agent.CurrentTask != nil {
+		return nil
+	}
+
+	// Get tasks assigned to this agent
+	tasks, err := m.taskManager.GetTasksByAssignee(agent.Name)
+	if err != nil {
+		return fmt.Errorf("failed to get tasks for agent %s: %w", agent.Name, err)
+	}
+
+	log.Printf("Processing %d tasks for agent %s", len(tasks), agent.Name)
+
+	for _, task := range tasks {
+		if task.Status == tm.StatusToDo || task.Status == tm.StatusPending {
+			if err := m.processTask(agent, task); err != nil {
+				log.Printf("Error processing task %s: %v", task.ID, err)
+				// Mark task as failed
+				task.Status = tm.StatusFailed
+				if err := m.taskManager.UpdateTask(task); err != nil {
+					log.Printf("Error updating failed task %s: %v", task.ID, err)
+				}
+				agent.Stats.TasksFailed++
+			} else {
+				agent.Stats.TasksCompleted++
+			}
+			// Update success rate
+			total := agent.Stats.TasksCompleted + agent.Stats.TasksFailed
+			if total > 0 {
+				agent.Stats.SuccessRate = float64(agent.Stats.TasksCompleted) / float64(total) * 100
+			}
+		}
+	}
+
+	return nil
+}
+
+// processTask processes a single task with an agent
+func (m *Manager) processTask(agent *Agent, task *tm.Task) error {
+	ctx := context.Background()
+	startTime := time.Now()
+
+	log.Printf("Agent %s processing task %s: %s", agent.Name, task.ID, task.Title)
+
+	// Mark task as in progress
+	task.Status = tm.StatusInProgress
+	agent.CurrentTask = &task.ID
+	if err := m.taskManager.UpdateTask(task); err != nil {
+		return fmt.Errorf("failed to update task status: %w", err)
+	}
+
+	// Generate solution using LLM
+	solution, err := m.generateSolution(ctx, agent, task)
+	if err != nil {
+		return fmt.Errorf("failed to generate solution: %w", err)
+	}
+
+	// Create Git branch and commit solution
+	branchName := m.generateBranchName(task)
+	if err := m.createAndCommitSolution(branchName, task, solution, agent); err != nil {
+		return fmt.Errorf("failed to commit solution: %w", err)
+	}
+
+	// Create pull request
+	prURL, err := m.createPullRequest(ctx, task, solution, agent, branchName)
+	if err != nil {
+		return fmt.Errorf("failed to create pull request: %w", err)
+	}
+
+	// Update task as completed
+	task.Status = tm.StatusCompleted
+	task.Solution = solution
+	task.PullRequestURL = prURL
+	completedAt := time.Now()
+	task.CompletedAt = &completedAt
+	agent.CurrentTask = nil
+
+	if err := m.taskManager.UpdateTask(task); err != nil {
+		return fmt.Errorf("failed to update completed task: %w", err)
+	}
+
+	// Update agent stats
+	duration := time.Since(startTime)
+	if agent.Stats.AvgTime == 0 {
+		agent.Stats.AvgTime = duration.Milliseconds()
+	} else {
+		agent.Stats.AvgTime = (agent.Stats.AvgTime + duration.Milliseconds()) / 2
+	}
+
+	log.Printf("Task %s completed by agent %s in %v. PR: %s", task.ID, agent.Name, duration, prURL)
+	return nil
+}
+
+// generateSolution uses the agent's LLM to generate a solution
+func (m *Manager) generateSolution(ctx context.Context, agent *Agent, task *tm.Task) (string, error) {
+	prompt := m.buildTaskPrompt(task)
+
+	req := llm.ChatCompletionRequest{
+		Model: agent.Model,
+		Messages: []llm.Message{
+			{
+				Role:    llm.RoleSystem,
+				Content: agent.SystemPrompt,
+			},
+			{
+				Role:    llm.RoleUser,
+				Content: prompt,
+			},
+		},
+		MaxTokens:   agent.MaxTokens,
+		Temperature: agent.Temperature,
+	}
+
+	resp, err := agent.Provider.ChatCompletion(ctx, req)
+	if err != nil {
+		return "", fmt.Errorf("LLM request failed: %w", err)
+	}
+
+	if len(resp.Choices) == 0 {
+		return "", fmt.Errorf("no response from LLM")
+	}
+
+	return resp.Choices[0].Message.Content, nil
+}
+
+// buildTaskPrompt creates a detailed prompt for the LLM
+func (m *Manager) buildTaskPrompt(task *tm.Task) string {
+	return fmt.Sprintf(`Task: %s
+
+Priority: %s
+Description: %s
+
+Please provide a complete solution for this task. Include:
+1. Detailed implementation plan
+2. Code changes needed (if applicable)
+3. Files to be created or modified
+4. Testing considerations
+5. Any dependencies or prerequisites
+
+Your response should be comprehensive and actionable.`,
+		task.Title,
+		task.Priority,
+		task.Description)
+}
+
+// generateBranchName creates a Git branch name for the task
+func (m *Manager) generateBranchName(task *tm.Task) string {
+	// Clean title for use in branch name
+	cleanTitle := strings.ToLower(task.Title)
+	cleanTitle = strings.ReplaceAll(cleanTitle, " ", "-")
+	cleanTitle = strings.ReplaceAll(cleanTitle, "/", "-")
+	// Remove special characters
+	var result strings.Builder
+	for _, r := range cleanTitle {
+		if (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '-' {
+			result.WriteRune(r)
+		}
+	}
+	cleanTitle = result.String()
+
+	// Limit length
+	if len(cleanTitle) > 40 {
+		cleanTitle = cleanTitle[:40]
+	}
+
+	return fmt.Sprintf("%s%s-%s", m.config.Git.BranchPrefix, task.ID, cleanTitle)
+}
+
+// createAndCommitSolution creates a Git branch and commits the solution using per-agent clones
+func (m *Manager) createAndCommitSolution(branchName string, task *tm.Task, solution string, agent *Agent) error {
+	ctx := context.Background()
+
+	// Get agent's dedicated Git clone
+	clonePath, err := m.cloneManager.GetAgentClonePath(agent.Name)
+	if err != nil {
+		return fmt.Errorf("failed to get agent clone: %w", err)
+	}
+
+	log.Printf("Agent %s working in clone: %s", agent.Name, clonePath)
+
+	// Refresh the clone with latest changes
+	if err := m.cloneManager.RefreshAgentClone(agent.Name); err != nil {
+		log.Printf("Warning: Failed to refresh clone for agent %s: %v", agent.Name, err)
+	}
+
+	// All Git operations use the agent's clone directory
+	gitCmd := func(args ...string) *exec.Cmd {
+		return exec.CommandContext(ctx, "git", append([]string{"-C", clonePath}, args...)...)
+	}
+
+	// Ensure we're on main branch before creating new branch
+	cmd := gitCmd("checkout", "main")
+	if err := cmd.Run(); err != nil {
+		// Try master branch if main doesn't exist
+		cmd = gitCmd("checkout", "master")
+		if err := cmd.Run(); err != nil {
+			return fmt.Errorf("failed to checkout main/master branch: %w", err)
+		}
+	}
+
+	// Create branch
+	cmd = gitCmd("checkout", "-b", branchName)
+	if err := cmd.Run(); err != nil {
+		return fmt.Errorf("failed to create branch: %w", err)
+	}
+
+	// Create solution file in agent's clone
+	solutionDir := filepath.Join(clonePath, "tasks", "solutions")
+	if err := os.MkdirAll(solutionDir, 0755); err != nil {
+		return fmt.Errorf("failed to create solution directory: %w", err)
+	}
+
+	solutionFile := filepath.Join(solutionDir, fmt.Sprintf("%s-solution.md", task.ID))
+	solutionContent := fmt.Sprintf(`# Solution for Task: %s
+
+**Agent:** %s (%s)  
+**Model:** %s  
+**Completed:** %s
+
+## Task Description
+%s
+
+## Solution
+%s
+
+---
+*Generated by Staff AI Agent System*
+`, task.Title, agent.Name, agent.Role, agent.Model, time.Now().Format(time.RFC3339), task.Description, solution)
+
+	if err := os.WriteFile(solutionFile, []byte(solutionContent), 0644); err != nil {
+		return fmt.Errorf("failed to write solution file: %w", err)
+	}
+
+	// Stage files
+	relativeSolutionFile := filepath.Join("tasks", "solutions", fmt.Sprintf("%s-solution.md", task.ID))
+	cmd = gitCmd("add", relativeSolutionFile)
+	if err := cmd.Run(); err != nil {
+		return fmt.Errorf("failed to stage files: %w", err)
+	}
+
+	// Commit changes
+	commitMsg := m.buildCommitMessage(task, agent)
+	cmd = gitCmd("commit", "-m", commitMsg)
+	if err := cmd.Run(); err != nil {
+		return fmt.Errorf("failed to commit: %w", err)
+	}
+
+	// Push branch
+	cmd = gitCmd("push", "-u", "origin", branchName)
+	if err := cmd.Run(); err != nil {
+		return fmt.Errorf("failed to push branch: %w", err)
+	}
+
+	log.Printf("Agent %s successfully pushed branch %s", agent.Name, branchName)
+	return nil
+}
+
+// buildCommitMessage creates a commit message from template
+func (m *Manager) buildCommitMessage(task *tm.Task, agent *Agent) string {
+	template := m.config.Git.CommitMessageTemplate
+
+	replacements := map[string]string{
+		"{task_id}":    task.ID,
+		"{task_title}": task.Title,
+		"{agent_name}": agent.Name,
+		"{solution}":   "See solution file for details",
+	}
+
+	result := template
+	for placeholder, value := range replacements {
+		result = strings.ReplaceAll(result, placeholder, value)
+	}
+
+	return result
+}
+
+// createPullRequest creates a GitHub pull request
+func (m *Manager) createPullRequest(ctx context.Context, task *tm.Task, solution string, agent *Agent, branchName string) (string, error) {
+	title := fmt.Sprintf("Task %s: %s", task.ID, task.Title)
+
+	// Build PR description from template
+	description := m.buildPRDescription(task, solution, agent)
+
+	options := git.PullRequestOptions{
+		Title:       title,
+		Description: description,
+		HeadBranch:  branchName,
+		BaseBranch:  "main",
+		Labels:      []string{"ai-generated", "staff-agent", strings.ToLower(agent.Role)},
+		Draft:       false,
+	}
+
+	pr, err := m.prProvider.CreatePullRequest(ctx, options)
+	if err != nil {
+		return "", fmt.Errorf("failed to create PR: %w", err)
+	}
+
+	return fmt.Sprintf("https://github.com/%s/%s/pull/%d", m.config.GitHub.Owner, m.config.GitHub.Repo, pr.Number), nil
+}
+
+// buildPRDescription creates PR description from template
+func (m *Manager) buildPRDescription(task *tm.Task, solution string, agent *Agent) string {
+	template := m.config.Git.PRTemplate
+
+	// Truncate solution for PR if too long
+	truncatedSolution := solution
+	if len(solution) > 1000 {
+		truncatedSolution = solution[:1000] + "...\n\n*See solution file for complete details*"
+	}
+
+	replacements := map[string]string{
+		"{task_id}":          task.ID,
+		"{task_title}":       task.Title,
+		"{task_description}": task.Description,
+		"{agent_name}":       fmt.Sprintf("%s (%s)", agent.Name, agent.Role),
+		"{priority}":         string(task.Priority),
+		"{solution}":         truncatedSolution,
+		"{files_changed}":    fmt.Sprintf("- `tasks/solutions/%s-solution.md`", task.ID),
+	}
+
+	result := template
+	for placeholder, value := range replacements {
+		result = strings.ReplaceAll(result, placeholder, value)
+	}
+
+	return result
+}
+
+// AutoAssignTask automatically assigns a task to the best matching agent
+func (m *Manager) AutoAssignTask(taskID string) error {
+	task, err := m.taskManager.GetTask(taskID)
+	if err != nil {
+		return fmt.Errorf("failed to get task: %w", err)
+	}
+
+	agentName, err := m.autoAssigner.AssignTask(task)
+	if err != nil {
+		return fmt.Errorf("failed to auto-assign task: %w", err)
+	}
+
+	task.Assignee = agentName
+	if err := m.taskManager.UpdateTask(task); err != nil {
+		return fmt.Errorf("failed to update task assignment: %w", err)
+	}
+
+	explanation := m.autoAssigner.GetRecommendationExplanation(task, agentName)
+	log.Printf("Auto-assigned task %s to %s: %s", taskID, agentName, explanation)
+
+	return nil
+}
+
+// GetAgentStatus returns the status of all agents
+func (m *Manager) GetAgentStatus() map[string]AgentInfo {
+	status := make(map[string]AgentInfo)
+
+	for name, agent := range m.agents {
+		agentStatus := StatusIdle
+		if m.isRunning[name] {
+			if agent.CurrentTask != nil {
+				agentStatus = StatusRunning
+			}
+		} else {
+			agentStatus = StatusStopped
+		}
+
+		status[name] = AgentInfo{
+			Name:        agent.Name,
+			Role:        agent.Role,
+			Model:       agent.Model,
+			Status:      agentStatus,
+			CurrentTask: agent.CurrentTask,
+			Stats:       agent.Stats,
+		}
+	}
+
+	return status
+}
+
+// IsAgentRunning checks if an agent is currently running
+func (m *Manager) IsAgentRunning(agentName string) bool {
+	return m.isRunning[agentName]
+}
+
+// Close shuts down the agent manager
+func (m *Manager) Close() error {
+	// Stop all running agents
+	for agentName := range m.isRunning {
+		if m.isRunning[agentName] {
+			m.StopAgent(agentName)
+		}
+	}
+
+	// Close all LLM providers
+	for _, agent := range m.agents {
+		if err := agent.Provider.Close(); err != nil {
+			log.Printf("Error closing provider for agent %s: %v", agent.Name, err)
+		}
+	}
+
+	// Cleanup all agent Git clones
+	if err := m.cloneManager.CleanupAllClones(); err != nil {
+		log.Printf("Error cleaning up agent clones: %v", err)
+	}
+
+	return nil
+}
