Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
FROM python:3.11-slim

ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1

WORKDIR /app

# curl is used for the container healthcheck
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates curl \
&& rm -rf /var/lib/apt/lists/*

# Rogue uses uv + uv.lock for reproducible installs
RUN pip install --no-cache-dir uv

# Copy dependency manifests first for better caching
COPY pyproject.toml uv.lock ./
COPY .python-version* ./

# Copy the repo
COPY . .

# Install deps from lockfile
RUN uv sync --locked --no-dev

# AgentCore HTTP runtime expects the service to listen on 8080
EXPOSE 8080

# Optional but recommended: container-level healthcheck uses AgentCore /ping
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD curl -fsS http://localhost:8080/ping || exit 1

# Start the existing server on the required host/port
CMD ["uv", "run", "python", "-m", "rogue.run_server", "--host", "0.0.0.0", "--port", "8080"]
26 changes: 26 additions & 0 deletions rogue/server/api/agentcore.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from fastapi import APIRouter, BackgroundTasks, Depends
from rogue_sdk.types import EvaluationRequest, EvaluationResponse
from .evaluation import get_evaluation_service, enqueue_evaluation
from ..services.evaluation_service import EvaluationService

router = APIRouter(tags=["agentcore"])


@router.get("/ping")
def ping():
return {"status": "Healthy"}


@router.post("/invocations", response_model=EvaluationResponse)
async def invocations(
request: EvaluationRequest,
background_tasks: BackgroundTasks,
evaluation_service: EvaluationService = Depends(get_evaluation_service),
):
# different entrypoint to /evaluations to meet agentcore convention
return await enqueue_evaluation(
request=request,
background_tasks=background_tasks,
evaluation_service=evaluation_service,
endpoint="/invocations",
)
22 changes: 18 additions & 4 deletions rogue/server/api/evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ def get_evaluation_service():
return EvaluationService()


@router.post("", response_model=EvaluationResponse)
async def create_evaluation(
async def enqueue_evaluation(
request: EvaluationRequest,
background_tasks: BackgroundTasks,
evaluation_service: EvaluationService = Depends(get_evaluation_service),
evaluation_service: EvaluationService,
endpoint: str,
):
job_id = str(uuid.uuid4())

Expand All @@ -46,7 +46,7 @@ async def create_evaluation(

# Build extra logging info
extra_info = {
"endpoint": "/evaluations",
"endpoint": endpoint,
"method": "POST",
"agent_url": str(request.agent_config.evaluated_agent_url),
"scenario_count": scenario_count,
Expand Down Expand Up @@ -82,6 +82,20 @@ async def create_evaluation(
)


@router.post("", response_model=EvaluationResponse)
async def create_evaluation(
request: EvaluationRequest,
background_tasks: BackgroundTasks,
evaluation_service: EvaluationService = Depends(get_evaluation_service),
):
return await enqueue_evaluation(
request=request,
background_tasks=background_tasks,
evaluation_service=evaluation_service,
endpoint="/evaluations",
)


@router.get("", response_model=JobListResponse)
async def list_evaluations(
status: Optional[EvaluationStatus] = None,
Expand Down
2 changes: 2 additions & 0 deletions rogue/server/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from .api.llm import router as llm_router
from .api.red_team import router as red_team_router
from .websocket.manager import websocket_router
from .api.agentcore import router as ac_router

logger = get_logger(__name__)

Expand Down Expand Up @@ -67,6 +68,7 @@ def create_app() -> FastAPI:
app.include_router(llm_router, prefix="/api/v1")
app.include_router(interview_router, prefix="/api/v1")
app.include_router(websocket_router, prefix="/api/v1")
app.include_router(ac_router, prefix="")

return app

Expand Down
Loading