The file C:\Users\MikeSwanson\claude-projects\Autocode-remix\Autocode-fork\backend\app\routers\agents.py has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
     1→"""
     2→Agents Router
     3→=============
     4→
     5→API endpoints for agent management and control.
     6→"""
     7→
     8→from datetime import datetime
     9→from typing import Optional, Dict, Any
    10→
    11→from fastapi import APIRouter, Depends, HTTPException, status
    12→from pydantic import BaseModel
    13→from sqlalchemy import select
    14→from sqlalchemy.ext.asyncio import AsyncSession
    15→
    16→from ..database import get_db
    17→from ..models import Project
    18→from .websocket import broadcast_agent_log
    19→
    20→router = APIRouter(prefix="/api/projects", tags=["agents"])
    21→
    22→
    23→# ============================================================================
    24→# Agent State Storage (in-memory for now)
    25→# ============================================================================
    26→
    27→# Store agent states in memory (will be replaced with persistent storage later)
    28→_agent_states: Dict[str, Dict[str, Dict[str, Any]]] = {}
    29→
    30→
    31→def get_agent_state(project_name: str, agent_id: str) -> Dict[str, Any]:
    32→    """Get agent state for a project."""
    33→    if project_name not in _agent_states:
    34→        _agent_states[project_name] = {
    35→            "A": {"status": "stopped", "started_at": None, "paused_at": None},
    36→            "B": {"status": "stopped", "started_at": None, "paused_at": None},
    37→        }
    38→    return _agent_states[project_name].get(agent_id, {"status": "stopped"})
    39→
    40→
    41→def set_agent_state(project_name: str, agent_id: str, state: Dict[str, Any]):
    42→    """Set agent state for a project."""
    43→    if project_name not in _agent_states:
    44→        _agent_states[project_name] = {
    45→            "A": {"status": "stopped", "started_at": None, "paused_at": None},
    46→            "B": {"status": "stopped", "started_at": None, "paused_at": None},
    47→        }
    48→    _agent_states[project_name][agent_id] = state
    49→
    50→
    51→# ============================================================================
    52→# Pydantic Schemas
    53→# ============================================================================
    54→
    55→class AgentStatus(BaseModel):
    56→    """Schema for agent status."""
    57→    status: str  # "stopped", "running", "paused", "stalled"
    58→    started_at: Optional[datetime] = None
    59→    paused_at: Optional[datetime] = None
    60→
    61→
    62→class AgentStatusResponse(BaseModel):
    63→    """Schema for agent status response (both agents)."""
    64→    agent_a: AgentStatus
    65→    agent_b: AgentStatus
    66→
    67→
    68→class AgentActionResponse(BaseModel):
    69→    """Schema for agent action response."""
    70→    agent_id: str
    71→    status: str
    72→    message: str
    73→
    74→
    75→class TestLogRequest(BaseModel):
    76→    """Schema for test log request."""
    77→    log_type: str = "info"  # "info", "error", "tool", "permission"
    78→    content: str
    79→
    80→
    81→# ============================================================================
    82→# API Endpoints
    83→# ============================================================================
    84→
    85→@router.get("/{name}/agents/status", response_model=AgentStatusResponse)
    86→async def get_agents_status(name: str, db: AsyncSession = Depends(get_db)):
    87→    """Get status of both agents for a project."""
    88→    # Verify project exists
    89→    result = await db.execute(select(Project).where(Project.name == name))
    90→    project = result.scalar_one_or_none()
    91→
    92→    if not project:
    93→        raise HTTPException(
    94→            status_code=status.HTTP_404_NOT_FOUND,
    95→            detail=f"Project '{name}' not found"
    96→        )
    97→
    98→    agent_a = get_agent_state(name, "A")
    99→    agent_b = get_agent_state(name, "B")
   100→
   101→    return AgentStatusResponse(
   102→        agent_a=AgentStatus(**agent_a),
   103→        agent_b=AgentStatus(**agent_b),
   104→    )
   105→
   106→
   107→@router.post("/{name}/agents/{agent_id}/start", response_model=AgentActionResponse)
   108→async def start_agent(name: str, agent_id: str, db: AsyncSession = Depends(get_db)):
   109→    """Start an agent for a project."""
   110→    # Validate agent_id
   111→    if agent_id not in ("A", "B"):
   112→        raise HTTPException(
   113→            status_code=status.HTTP_400_BAD_REQUEST,
   114→            detail="Agent ID must be 'A' or 'B'"
   115→        )
   116→
   117→    # Verify project exists
   118→    result = await db.execute(select(Project).where(Project.name == name))
   119→    project = result.scalar_one_or_none()
   120→
   121→    if not project:
   122→        raise HTTPException(
   123→            status_code=status.HTTP_404_NOT_FOUND,
   124→            detail=f"Project '{name}' not found"
   125→        )
   126→
   127→    current_state = get_agent_state(name, agent_id)
   128→
   129→    if current_state["status"] == "running":
   130→        raise HTTPException(
   131→            status_code=status.HTTP_400_BAD_REQUEST,
   132→            detail=f"Agent {agent_id} is already running"
   133→        )
   134→
   135→    # Update state to running
   136→    set_agent_state(name, agent_id, {
   137→        "status": "running",
   138→        "started_at": datetime.utcnow(),
   139→        "paused_at": None,
   140→    })
   141→
   142→    return AgentActionResponse(
   143→        agent_id=agent_id,
   144→        status="running",
   145→        message=f"Agent {agent_id} started successfully"
   146→    )
   147→
   148→
   149→@router.post("/{name}/agents/{agent_id}/stop", response_model=AgentActionResponse)
   150→async def stop_agent(name: str, agent_id: str, db: AsyncSession = Depends(get_db)):
   151→    """Stop an agent for a project."""
   152→    # Validate agent_id
   153→    if agent_id not in ("A", "B"):
   154→        raise HTTPException(
   155→            status_code=status.HTTP_400_BAD_REQUEST,
   156→            detail="Agent ID must be 'A' or 'B'"
   157→        )
   158→
   159→    # Verify project exists
   160→    result = await db.execute(select(Project).where(Project.name == name))
   161→    project = result.scalar_one_or_none()
   162→
   163→    if not project:
   164→        raise HTTPException(
   165→            status_code=status.HTTP_404_NOT_FOUND,
   166→            detail=f"Project '{name}' not found"
   167→        )
   168→
   169→    # Update state to stopped
   170→    set_agent_state(name, agent_id, {
   171→        "status": "stopped",
   172→        "started_at": None,
   173→        "paused_at": None,
   174→    })
   175→
   176→    return AgentActionResponse(
   177→        agent_id=agent_id,
   178→        status="stopped",
   179→        message=f"Agent {agent_id} stopped successfully"
   180→    )
   181→
   182→
   183→@router.post("/{name}/agents/{agent_id}/pause", response_model=AgentActionResponse)
   184→async def pause_agent(name: str, agent_id: str, db: AsyncSession = Depends(get_db)):
   185→    """Pause an agent for a project."""
   186→    # Validate agent_id
   187→    if agent_id not in ("A", "B"):
   188→        raise HTTPException(
   189→            status_code=status.HTTP_400_BAD_REQUEST,
   190→            detail="Agent ID must be 'A' or 'B'"
   191→        )
   192→
   193→    # Verify project exists
   194→    result = await db.execute(select(Project).where(Project.name == name))
   195→    project = result.scalar_one_or_none()
   196→
   197→    if not project:
   198→        raise HTTPException(
   199→            status_code=status.HTTP_404_NOT_FOUND,
   200→            detail=f"Project '{name}' not found"
   201→        )
   202→
   203→    current_state = get_agent_state(name, agent_id)
   204→
   205→    if current_state["status"] != "running":
   206→        raise HTTPException(
   207→            status_code=status.HTTP_400_BAD_REQUEST,
   208→            detail=f"Agent {agent_id} is not running (current status: {current_state['status']})"
   209→        )
   210→
   211→    # Update state to paused
   212→    set_agent_state(name, agent_id, {
   213→        "status": "paused",
   214→        "started_at": current_state.get("started_at"),
   215→        "paused_at": datetime.utcnow(),
   216→    })
   217→
   218→    return AgentActionResponse(
   219→        agent_id=agent_id,
   220→        status="paused",
   221→        message=f"Agent {agent_id} paused successfully"
   222→    )
   223→
   224→
   225→@router.post("/{name}/agents/{agent_id}/resume", response_model=AgentActionResponse)
   226→async def resume_agent(name: str, agent_id: str, db: AsyncSession = Depends(get_db)):
   227→    """Resume a paused agent for a project."""
   228→    # Validate agent_id
   229→    if agent_id not in ("A", "B"):
   230→        raise HTTPException(
   231→            status_code=status.HTTP_400_BAD_REQUEST,
   232→            detail="Agent ID must be 'A' or 'B'"
   233→        )
   234→
   235→    # Verify project exists
   236→    result = await db.execute(select(Project).where(Project.name == name))
   237→    project = result.scalar_one_or_none()
   238→
   239→    if not project:
   240→        raise HTTPException(
   241→            status_code=status.HTTP_404_NOT_FOUND,
   242→            detail=f"Project '{name}' not found"
   243→        )
   244→
   245→    current_state = get_agent_state(name, agent_id)
   246→
   247→    if current_state["status"] != "paused":
   248→        raise HTTPException(
   249→            status_code=status.HTTP_400_BAD_REQUEST,
   250→            detail=f"Agent {agent_id} is not paused (current status: {current_state['status']})"
   251→        )
   252→
   253→    # Update state to running
   254→    set_agent_state(name, agent_id, {
   255→        "status": "running",
   256→        "started_at": current_state.get("started_at"),
   257→        "paused_at": None,
   258→    })
   259→
   260→    return AgentActionResponse(
   261→        agent_id=agent_id,
   262→        status="running",
   263→        message=f"Agent {agent_id} resumed successfully"
   264→    )
   265→
   266→
   267→@router.post("/{name}/agents/{agent_id}/test-log")
   268→async def send_test_log(
   269→    name: str,
   270→    agent_id: str,
   271→    request: TestLogRequest,
   272→    db: AsyncSession = Depends(get_db)
   273→):
   274→    """Send a test log message to the terminal (for testing purposes)."""
   275→    # Validate agent_id
   276→    if agent_id not in ("A", "B"):
   277→        raise HTTPException(
   278→            status_code=status.HTTP_400_BAD_REQUEST,
   279→            detail="Agent ID must be 'A' or 'B'"
   280→        )
   281→
   282→    # Verify project exists
   283→    result = await db.execute(select(Project).where(Project.name == name))
   284→    project = result.scalar_one_or_none()
   285→
   286→    if not project:
   287→        raise HTTPException(
   288→            status_code=status.HTTP_404_NOT_FOUND,
   289→            detail=f"Project '{name}' not found"
   290→        )
   291→
   292→    # Broadcast the log message
   293→    await broadcast_agent_log(name, agent_id, request.log_type, request.content)
   294→
   295→    return {"status": "ok", "message": "Log sent successfully"}
   296→

"""
Agents Router
=============

API endpoints for agent management and control.
"""

from datetime import datetime
from typing import Optional, Dict, Any

from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from ..database import get_db
from ..models import Project
from .websocket import broadcast_agent_log

router = APIRouter(prefix="/api/projects", tags=["agents"])

# ============================================================================
# Agent State Storage (in-memory for now)
# ============================================================================

# Store agent states in memory (will be replaced with persistent storage later)
_agent_states: Dict[str, Dict[str, Dict[str, Any]]] = {}

def get_agent_state(project_name: str, agent_id: str) -> Dict[str, Any]:
    """Get agent state for a project."""
    if project_name not in _agent_states:
        _agent_states[project_name] = {
            "A": {"status": "stopped", "started_at": None, "paused_at": None},
            "B": {"status": "stopped", "started_at": None, "paused_at": None},
        }
    return _agent_states[project_name].get(agent_id, {"status": "stopped"})

def set_agent_state(project_name: str, agent_id: str, state: Dict[str, Any]):
    """Set agent state for a project."""
    if project_name not in _agent_states:
        _agent_states[project_name] = {
            "A": {"status": "stopped", "started_at": None, "paused_at": None},
            "B": {"status": "stopped", "started_at": None, "paused_at": None},
        }
    _agent_states[project_name][agent_id] = state

# ============================================================================
# Pydantic Schemas
# ============================================================================

class AgentStatus(BaseModel):
    """Schema for agent status."""
    status: str  # "stopped", "running", "paused", "stalled"
    started_at: Optional[datetime] = None
    paused_at: Optional[datetime] = None

class AgentStatusResponse(BaseModel):
    """Schema for agent status response (both agents)."""
    agent_a: AgentStatus
    agent_b: AgentStatus

class AgentActionResponse(BaseModel):
    """Schema for agent action response."""
    agent_id: str
    status: str
    message: str

class TestLogRequest(BaseModel):
    """Schema for test log request."""
    log_type: str = "info"  # "info", "error", "tool", "permission"
    content: str

# ============================================================================
# API Endpoints
# ============================================================================

@router.get("/{name}/agents/status", response_model=AgentStatusResponse)
async def get_agents_status(name: str, db: AsyncSession = Depends(get_db)):
    """Get status of both agents for a project."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    agent_a = get_agent_state(name, "A")
    agent_b = get_agent_state(name, "B")

    return AgentStatusResponse(
        agent_a=AgentStatus(**agent_a),
        agent_b=AgentStatus(**agent_b),
    )

@router.post("/{name}/agents/{agent_id}/start", response_model=AgentActionResponse)
async def start_agent(name: str, agent_id: str, db: AsyncSession = Depends(get_db)):
    """Start an agent for a project."""
    # Validate agent_id
    if agent_id not in ("A", "B"):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Agent ID must be 'A' or 'B'"
        )

    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    current_state = get_agent_state(name, agent_id)

    if current_state["status"] == "running":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Agent {agent_id} is already running"
        )

    # Update state to running
    set_agent_state(name, agent_id, {
        "status": "running",
        "started_at": datetime.utcnow(),
        "paused_at": None,
    })

    return AgentActionResponse(
        agent_id=agent_id,
        status="running",
        message=f"Agent {agent_id} started successfully"
    )

@router.post("/{name}/agents/{agent_id}/stop", response_model=AgentActionResponse)
async def stop_agent(name: str, agent_id: str, db: AsyncSession = Depends(get_db)):
    """Stop an agent for a project."""
    # Validate agent_id
    if agent_id not in ("A", "B"):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Agent ID must be 'A' or 'B'"
        )

    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Update state to stopped
    set_agent_state(name, agent_id, {
        "status": "stopped",
        "started_at": None,
        "paused_at": None,
    })

    return AgentActionResponse(
        agent_id=agent_id,
        status="stopped",
        message=f"Agent {agent_id} stopped successfully"
    )

@router.post("/{name}/agents/{agent_id}/pause", response_model=AgentActionResponse)
async def pause_agent(name: str, agent_id: str, db: AsyncSession = Depends(get_db)):
    """Pause an agent for a project."""
    # Validate agent_id
    if agent_id not in ("A", "B"):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Agent ID must be 'A' or 'B'"
        )

    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    current_state = get_agent_state(name, agent_id)

    if current_state["status"] != "running":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Agent {agent_id} is not running (current status: {current_state['status']})"
        )

    # Update state to paused
    set_agent_state(name, agent_id, {
        "status": "paused",
        "started_at": current_state.get("started_at"),
        "paused_at": datetime.utcnow(),
    })

    return AgentActionResponse(
        agent_id=agent_id,
        status="paused",
        message=f"Agent {agent_id} paused successfully"
    )

@router.post("/{name}/agents/{agent_id}/resume", response_model=AgentActionResponse)
async def resume_agent(name: str, agent_id: str, db: AsyncSession = Depends(get_db)):
    """Resume a paused agent for a project."""
    # Validate agent_id
    if agent_id not in ("A", "B"):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Agent ID must be 'A' or 'B'"
        )

    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    current_state = get_agent_state(name, agent_id)

    if current_state["status"] != "paused":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Agent {agent_id} is not paused (current status: {current_state['status']})"
        )

    # Update state to running
    set_agent_state(name, agent_id, {
        "status": "running",
        "started_at": current_state.get("started_at"),
        "paused_at": None,
    })

    return AgentActionResponse(
        agent_id=agent_id,
        status="running",
        message=f"Agent {agent_id} resumed successfully"
    )

@router.post("/{name}/agents/{agent_id}/test-log")
async def send_test_log(
    name: str,
    agent_id: str,
    request: TestLogRequest,
    db: AsyncSession = Depends(get_db)
):
    """Send a test log message to the terminal (for testing purposes)."""
    # Validate agent_id
    if agent_id not in ("A", "B"):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Agent ID must be 'A' or 'B'"
        )

    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Broadcast the log message
    await broadcast_agent_log(name, agent_id, request.log_type, request.content)

    return {"status": "ok", "message": "Log sent successfully"}

+from .websocket import broadcast_agent_log

+    log_type: str = "info"  # "info", "error", "tool", "permission"

+    """Send a test log message to the terminal (for testing purposes)."""

+            status_code=status.HTTP_400_BAD_REQUEST,

+            detail="Agent ID must be 'A' or 'B'"

+    result = await db.execute(select(Project).where(Project.name == name))

+    project = result.scalar_one_or_none()

+            status_code=status.HTTP_404_NOT_FOUND,

+            detail=f"Project '{name}' not found"

+    await broadcast_agent_log(name, agent_id, request.log_type, request.content)

+    return {"status": "ok", "message": "Log sent successfully"}

"""
Agents Router
=============

API endpoints for agent management and control.
"""

from datetime import datetime
from typing import Optional, Dict, Any

from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from ..database import get_db
from ..models import Project

router = APIRouter(prefix="/api/projects", tags=["agents"])

# ============================================================================
# Agent State Storage (in-memory for now)
# ============================================================================

# Store agent states in memory (will be replaced with persistent storage later)
_agent_states: Dict[str, Dict[str, Dict[str, Any]]] = {}

def get_agent_state(project_name: str, agent_id: str) -> Dict[str, Any]:
    """Get agent state for a project."""
    if project_name not in _agent_states:
        _agent_states[project_name] = {
            "A": {"status": "stopped", "started_at": None, "paused_at": None},
            "B": {"status": "stopped", "started_at": None, "paused_at": None},
        }
    return _agent_states[project_name].get(agent_id, {"status": "stopped"})

def set_agent_state(project_name: str, agent_id: str, state: Dict[str, Any]):
    """Set agent state for a project."""
    if project_name not in _agent_states:
        _agent_states[project_name] = {
            "A": {"status": "stopped", "started_at": None, "paused_at": None},
            "B": {"status": "stopped", "started_at": None, "paused_at": None},
        }
    _agent_states[project_name][agent_id] = state

# ============================================================================
# Pydantic Schemas
# ============================================================================

class AgentStatus(BaseModel):
    """Schema for agent status."""
    status: str  # "stopped", "running", "paused", "stalled"
    started_at: Optional[datetime] = None
    paused_at: Optional[datetime] = None

class AgentStatusResponse(BaseModel):
    """Schema for agent status response (both agents)."""
    agent_a: AgentStatus
    agent_b: AgentStatus

class AgentActionResponse(BaseModel):
    """Schema for agent action response."""
    agent_id: str
    status: str
    message: str

# ============================================================================
# API Endpoints
# ============================================================================

@router.get("/{name}/agents/status", response_model=AgentStatusResponse)
async def get_agents_status(name: str, db: AsyncSession = Depends(get_db)):
    """Get status of both agents for a project."""
    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    agent_a = get_agent_state(name, "A")
    agent_b = get_agent_state(name, "B")

    return AgentStatusResponse(
        agent_a=AgentStatus(**agent_a),
        agent_b=AgentStatus(**agent_b),
    )

@router.post("/{name}/agents/{agent_id}/start", response_model=AgentActionResponse)
async def start_agent(name: str, agent_id: str, db: AsyncSession = Depends(get_db)):
    """Start an agent for a project."""
    # Validate agent_id
    if agent_id not in ("A", "B"):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Agent ID must be 'A' or 'B'"
        )

    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    current_state = get_agent_state(name, agent_id)

    if current_state["status"] == "running":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Agent {agent_id} is already running"
        )

    # Update state to running
    set_agent_state(name, agent_id, {
        "status": "running",
        "started_at": datetime.utcnow(),
        "paused_at": None,
    })

    return AgentActionResponse(
        agent_id=agent_id,
        status="running",
        message=f"Agent {agent_id} started successfully"
    )

@router.post("/{name}/agents/{agent_id}/stop", response_model=AgentActionResponse)
async def stop_agent(name: str, agent_id: str, db: AsyncSession = Depends(get_db)):
    """Stop an agent for a project."""
    # Validate agent_id
    if agent_id not in ("A", "B"):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Agent ID must be 'A' or 'B'"
        )

    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Update state to stopped
    set_agent_state(name, agent_id, {
        "status": "stopped",
        "started_at": None,
        "paused_at": None,
    })

    return AgentActionResponse(
        agent_id=agent_id,
        status="stopped",
        message=f"Agent {agent_id} stopped successfully"
    )

@router.post("/{name}/agents/{agent_id}/pause", response_model=AgentActionResponse)
async def pause_agent(name: str, agent_id: str, db: AsyncSession = Depends(get_db)):
    """Pause an agent for a project."""
    # Validate agent_id
    if agent_id not in ("A", "B"):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Agent ID must be 'A' or 'B'"
        )

    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    current_state = get_agent_state(name, agent_id)

    if current_state["status"] != "running":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Agent {agent_id} is not running (current status: {current_state['status']})"
        )

    # Update state to paused
    set_agent_state(name, agent_id, {
        "status": "paused",
        "started_at": current_state.get("started_at"),
        "paused_at": datetime.utcnow(),
    })

    return AgentActionResponse(
        agent_id=agent_id,
        status="paused",
        message=f"Agent {agent_id} paused successfully"
    )

@router.post("/{name}/agents/{agent_id}/resume", response_model=AgentActionResponse)
async def resume_agent(name: str, agent_id: str, db: AsyncSession = Depends(get_db)):
    """Resume a paused agent for a project."""
    # Validate agent_id
    if agent_id not in ("A", "B"):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Agent ID must be 'A' or 'B'"
        )

    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    current_state = get_agent_state(name, agent_id)

    if current_state["status"] != "paused":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Agent {agent_id} is not paused (current status: {current_state['status']})"
        )

    # Update state to running
    set_agent_state(name, agent_id, {
        "status": "running",
        "started_at": current_state.get("started_at"),
        "paused_at": None,
    })

    return AgentActionResponse(
        agent_id=agent_id,
        status="running",
        message=f"Agent {agent_id} resumed successfully"
    )


The file has been successfully updated. Using the Windows-style backslash path worked. Let me verify the changes by reading the file again.


     1→"""
     2→Agents Router
     3→=============
     4→
     5→API endpoints for agent management and control.
     6→"""
     7→
     8→from datetime import datetime
     9→from typing import Optional, Dict, Any
    10→
    11→from fastapi import APIRouter, Depends, HTTPException, status
    12→from pydantic import BaseModel
    13→from sqlalchemy import select
    14→from sqlalchemy.ext.asyncio import AsyncSession
    15→
    16→from ..database import get_db
    17→from ..models import Project
    18→from .websocket import broadcast_agent_log
    19→
    20→router = APIRouter(prefix="/api/projects", tags=["agents"])
    21→
    22→
    23→# ============================================================================
    24→# Agent State Storage (in-memory for now)
    25→# ============================================================================
    26→
    27→# Store agent states in memory (will be replaced with persistent storage later)
    28→_agent_states: Dict[str, Dict[str, Dict[str, Any]]] = {}
    29→
    30→
    31→def get_agent_state(project_name: str, agent_id: str) -> Dict[str, Any]:
    32→    """Get agent state for a project."""
    33→    if project_name not in _agent_states:
    34→        _agent_states[project_name] = {
    35→            "A": {"status": "stopped", "started_at": None, "paused_at": None},
    36→            "B": {"status": "stopped", "started_at": None, "paused_at": None},
    37→        }
    38→    return _agent_states[project_name].get(agent_id, {"status": "stopped"})
    39→
    40→
    41→def set_agent_state(project_name: str, agent_id: str, state: Dict[str, Any]):
    42→    """Set agent state for a project."""
    43→    if project_name not in _agent_states:
    44→        _agent_states[project_name] = {
    45→            "A": {"status": "stopped", "started_at": None, "paused_at": None},
    46→            "B": {"status": "stopped", "started_at": None, "paused_at": None},
    47→        }
    48→    _agent_states[project_name][agent_id] = state
    49→
    50→
    51→# ============================================================================
    52→# Pydantic Schemas
    53→# ============================================================================
    54→
    55→class AgentStatus(BaseModel):
    56→    """Schema for agent status."""
    57→    status: str  # "stopped", "running", "paused", "stalled"
    58→    started_at: Optional[datetime] = None
    59→    paused_at: Optional[datetime] = None
    60→
    61→
    62→class AgentStatusResponse(BaseModel):
    63→    """Schema for agent status response (both agents)."""
    64→    agent_a: AgentStatus
    65→    agent_b: AgentStatus
    66→
    67→
    68→class AgentActionResponse(BaseModel):
    69→    """Schema for agent action response."""
    70→    agent_id: str
    71→    status: str
    72→    message: str
    73→
    74→
    75→class TestLogRequest(BaseModel):
    76→    """Schema for test log request."""
    77→    log_type: str = "info"  # "info", "error", "tool", "permission"
    78→    content: str
    79→
    80→
    81→# ============================================================================
    82→# API Endpoints
    83→# ============================================================================
    84→
    85→@router.get("/{name}/agents/status", response_model=AgentStatusResponse)
    86→async def get_agents_status(name: str, db: AsyncSession = Depends(get_db)):
    87→    """Get status of both agents for a project."""
    88→    # Verify project exists
    89→    result = await db.execute(select(Project).where(Project.name == name))
    90→    project = result.scalar_one_or_none()
    91→
    92→    if not project:
    93→        raise HTTPException(
    94→            status_code=status.HTTP_404_NOT_FOUND,
    95→            detail=f"Project '{name}' not found"
    96→        )
    97→
    98→    agent_a = get_agent_state(name, "A")
    99→    agent_b = get_agent_state(name, "B")
   100→
   101→    return AgentStatusResponse(
   102→        agent_a=AgentStatus(**agent_a),
   103→        agent_b=AgentStatus(**agent_b),
   104→    )
   105→
   106→
   107→@router.post("/{name}/agents/{agent_id}/start", response_model=AgentActionResponse)
   108→async def start_agent(name: str, agent_id: str, db: AsyncSession = Depends(get_db)):
   109→    """Start an agent for a project."""
   110→    # Validate agent_id
   111→    if agent_id not in ("A", "B"):
   112→        raise HTTPException(
   113→            status_code=status.HTTP_400_BAD_REQUEST,
   114→            detail="Agent ID must be 'A' or 'B'"
   115→        )
   116→
   117→    # Verify project exists
   118→    result = await db.execute(select(Project).where(Project.name == name))
   119→    project = result.scalar_one_or_none()
   120→
   121→    if not project:
   122→        raise HTTPException(
   123→            status_code=status.HTTP_404_NOT_FOUND,
   124→            detail=f"Project '{name}' not found"
   125→        )
   126→
   127→    current_state = get_agent_state(name, agent_id)
   128→
   129→    if current_state["status"] == "running":
   130→        raise HTTPException(
   131→            status_code=status.HTTP_400_BAD_REQUEST,
   132→            detail=f"Agent {agent_id} is already running"
   133→        )
   134→
   135→    # Update state to running
   136→    set_agent_state(name, agent_id, {
   137→        "status": "running",
   138→        "started_at": datetime.utcnow(),
   139→        "paused_at": None,
   140→    })
   141→
   142→    return AgentActionResponse(
   143→        agent_id=agent_id,
   144→        status="running",
   145→        message=f"Agent {agent_id} started successfully"
   146→    )
   147→
   148→
   149→@router.post("/{name}/agents/{agent_id}/stop", response_model=AgentActionResponse)
   150→async def stop_agent(name: str, agent_id: str, db: AsyncSession = Depends(get_db)):
   151→    """Stop an agent for a project."""
   152→    # Validate agent_id
   153→    if agent_id not in ("A", "B"):
   154→        raise HTTPException(
   155→            status_code=status.HTTP_400_BAD_REQUEST,
   156→            detail="Agent ID must be 'A' or 'B'"
   157→        )
   158→
   159→    # Verify project exists
   160→    result = await db.execute(select(Project).where(Project.name == name))
   161→    project = result.scalar_one_or_none()
   162→
   163→    if not project:
   164→        raise HTTPException(
   165→            status_code=status.HTTP_404_NOT_FOUND,
   166→            detail=f"Project '{name}' not found"
   167→        )
   168→
   169→    # Update state to stopped
   170→    set_agent_state(name, agent_id, {
   171→        "status": "stopped",
   172→        "started_at": None,
   173→        "paused_at": None,
   174→    })
   175→
   176→    return AgentActionResponse(
   177→        agent_id=agent_id,
   178→        status="stopped",
   179→        message=f"Agent {agent_id} stopped successfully"
   180→    )
   181→
   182→
   183→@router.post("/{name}/agents/{agent_id}/pause", response_model=AgentActionResponse)
   184→async def pause_agent(name: str, agent_id: str, db: AsyncSession = Depends(get_db)):
   185→    """Pause an agent for a project."""
   186→    # Validate agent_id
   187→    if agent_id not in ("A", "B"):
   188→        raise HTTPException(
   189→            status_code=status.HTTP_400_BAD_REQUEST,
   190→            detail="Agent ID must be 'A' or 'B'"
   191→        )
   192→
   193→    # Verify project exists
   194→    result = await db.execute(select(Project).where(Project.name == name))
   195→    project = result.scalar_one_or_none()
   196→
   197→    if not project:
   198→        raise HTTPException(
   199→            status_code=status.HTTP_404_NOT_FOUND,
   200→            detail=f"Project '{name}' not found"
   201→        )
   202→
   203→    current_state = get_agent_state(name, agent_id)
   204→
   205→    if current_state["status"] != "running":
   206→        raise HTTPException(
   207→            status_code=status.HTTP_400_BAD_REQUEST,
   208→            detail=f"Agent {agent_id} is not running (current status: {current_state['status']})"
   209→        )
   210→
   211→    # Update state to paused
   212→    set_agent_state(name, agent_id, {
   213→        "status": "paused",
   214→        "started_at": current_state.get("started_at"),
   215→        "paused_at": datetime.utcnow(),
   216→    })
   217→
   218→    return AgentActionResponse(
   219→        agent_id=agent_id,
   220→        status="paused",
   221→        message=f"Agent {agent_id} paused successfully"
   222→    )
   223→
   224→
   225→@router.post("/{name}/agents/{agent_id}/resume", response_model=AgentActionResponse)
   226→async def resume_agent(name: str, agent_id: str, db: AsyncSession = Depends(get_db)):
   227→    """Resume a paused agent for a project."""
   228→    # Validate agent_id
   229→    if agent_id not in ("A", "B"):
   230→        raise HTTPException(
   231→            status_code=status.HTTP_400_BAD_REQUEST,
   232→            detail="Agent ID must be 'A' or 'B'"
   233→        )
   234→
   235→    # Verify project exists
   236→    result = await db.execute(select(Project).where(Project.name == name))
   237→    project = result.scalar_one_or_none()
   238→
   239→    if not project:
   240→        raise HTTPException(
   241→            status_code=status.HTTP_404_NOT_FOUND,
   242→            detail=f"Project '{name}' not found"
   243→        )
   244→
   245→    current_state = get_agent_state(name, agent_id)
   246→
   247→    if current_state["status"] != "paused":
   248→        raise HTTPException(
   249→            status_code=status.HTTP_400_BAD_REQUEST,
   250→            detail=f"Agent {agent_id} is not paused (current status: {current_state['status']})"
   251→        )
   252→
   253→    # Update state to running
   254→    set_agent_state(name, agent_id, {
   255→        "status": "running",
   256→        "started_at": current_state.get("started_at"),
   257→        "paused_at": None,
   258→    })
   259→
   260→    return AgentActionResponse(
   261→        agent_id=agent_id,
   262→        status="running",
   263→        message=f"Agent {agent_id} resumed successfully"
   264→    )
   265→
   266→
   267→@router.post("/{name}/agents/{agent_id}/test-log")
   268→async def send_test_log(
   269→    name: str,
   270→    agent_id: str,
   271→    request: TestLogRequest,
   272→    db: AsyncSession = Depends(get_db)
   273→):
   274→    """Send a test log message to the terminal (for testing purposes)."""
   275→    # Validate agent_id
   276→    if agent_id not in ("A", "B"):
   277→        raise HTTPException(
   278→            status_code=status.HTTP_400_BAD_REQUEST,
   279→            detail="Agent ID must be 'A' or 'B'"
   280→        )
   281→
   282→    # Verify project exists
   283→    result = await db.execute(select(Project).where(Project.name == name))
   284→    project = result.scalar_one_or_none()
   285→
   286→    if not project:
   287→        raise HTTPException(
   288→            status_code=status.HTTP_404_NOT_FOUND,
   289→            detail=f"Project '{name}' not found"
   290→        )
   291→
   292→    # Broadcast the log message
   293→    await broadcast_agent_log(name, agent_id, request.log_type, request.content)
   294→
   295→    return {"status": "ok", "message": "Log sent successfully"}
   296→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


The file has been successfully updated with all three requested changes. Here is a summary of the modifications made to `C:\Users\MikeSwanson\claude-projects\Autocode-remix\Autocode-fork\backend\app\routers\agents.py`:

## Changes Made

### 1. Added Import (line 18)
```python
from .websocket import broadcast_agent_log
```

### 2. Added TestLogRequest Schema (lines 75-78)
```python
class TestLogRequest(BaseModel):
    """Schema for test log request."""
    log_type: str = "info"  # "info", "error", "tool", "permission"
    content: str
```

### 3. Added Test Log Endpoint (lines 267-295)
```python
@router.post("/{name}/agents/{agent_id}/test-log")
async def send_test_log(
    name: str,
    agent_id: str,
    request: TestLogRequest,
    db: AsyncSession = Depends(get_db)
):
    """Send a test log message to the terminal (for testing purposes)."""
    # Validate agent_id
    if agent_id not in ("A", "B"):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Agent ID must be 'A' or 'B'"
        )

    # Verify project exists
    result = await db.execute(select(Project).where(Project.name == name))
    project = result.scalar_one_or_none()

    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Project '{name}' not found"
        )

    # Broadcast the log message
    await broadcast_agent_log(name, agent_id, request.log_type, request.content)

    return {"status": "ok", "message": "Log sent successfully"}
```

The new endpoint is available at `POST /api/projects/{name}/agents/{agent_id}/test-log` and accepts a JSON body with `log_type` (defaults to "info") and `content` fields. It validates the agent ID, verifies the project exists, broadcasts the log message via WebSocket, and returns a success response.