Task 007 implement agent job queue and fake runner path
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
from uuid import UUID
|
||||
|
||||
from fastapi import APIRouter, Body, Depends, HTTPException, Response, status
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from src.application.agent_jobs import (
|
||||
cancel_agent_job,
|
||||
claim_next_agent_job,
|
||||
complete_agent_job,
|
||||
create_test_codex_job,
|
||||
get_agent_job,
|
||||
list_agent_jobs,
|
||||
retry_agent_job,
|
||||
)
|
||||
from src.domain.auth import ADMIN_ROLES
|
||||
from src.domain.contracts import (
|
||||
AgentJobListResponse,
|
||||
AgentJobResponse,
|
||||
AgentJobTestCodexRequest,
|
||||
CurrentUser,
|
||||
)
|
||||
from src.infrastructure.repositories import BackendRepository
|
||||
from src.presentation.dependencies import get_repository, require_roles
|
||||
|
||||
|
||||
router = APIRouter(prefix="/api", tags=["agent-jobs"])
|
||||
internal_router = APIRouter(prefix="/internal/agent-jobs", include_in_schema=False)
|
||||
|
||||
|
||||
class AgentJobCompletionRequest(BaseModel):
|
||||
workspace_path: str | None = None
|
||||
stdout: str = ""
|
||||
stderr: str = ""
|
||||
exit_code: int | None = None
|
||||
duration_ms: int | None = Field(default=None, ge=0)
|
||||
output: dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
@router.post(
|
||||
"/agent-jobs/test-codex",
|
||||
response_model=AgentJobResponse,
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
)
|
||||
def post_test_codex_job(
|
||||
request: AgentJobTestCodexRequest = Body(
|
||||
default_factory=AgentJobTestCodexRequest
|
||||
),
|
||||
_: CurrentUser = Depends(require_roles(ADMIN_ROLES)),
|
||||
repository: BackendRepository = Depends(get_repository),
|
||||
) -> AgentJobResponse:
|
||||
return create_test_codex_job(repository, request)
|
||||
|
||||
|
||||
@router.get("/agent-jobs", response_model=AgentJobListResponse)
|
||||
def get_agent_jobs(
|
||||
_: CurrentUser = Depends(require_roles(ADMIN_ROLES)),
|
||||
repository: BackendRepository = Depends(get_repository),
|
||||
) -> AgentJobListResponse:
|
||||
return list_agent_jobs(repository)
|
||||
|
||||
|
||||
@router.get("/agent-jobs/{job_id}", response_model=AgentJobResponse)
|
||||
def get_agent_job_route(
|
||||
job_id: UUID,
|
||||
_: CurrentUser = Depends(require_roles(ADMIN_ROLES)),
|
||||
repository: BackendRepository = Depends(get_repository),
|
||||
) -> AgentJobResponse:
|
||||
try:
|
||||
return get_agent_job(repository, job_id)
|
||||
except LookupError as error:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not Found") from error
|
||||
|
||||
|
||||
@router.post(
|
||||
"/agent-jobs/{job_id}/retry",
|
||||
response_model=AgentJobResponse,
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
)
|
||||
def post_retry_agent_job(
|
||||
job_id: UUID,
|
||||
_: CurrentUser = Depends(require_roles(ADMIN_ROLES)),
|
||||
repository: BackendRepository = Depends(get_repository),
|
||||
) -> AgentJobResponse:
|
||||
try:
|
||||
return retry_agent_job(repository, job_id)
|
||||
except LookupError as error:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not Found") from error
|
||||
|
||||
|
||||
@router.post("/agent-jobs/{job_id}/cancel", response_model=AgentJobResponse)
|
||||
def post_cancel_agent_job(
|
||||
job_id: UUID,
|
||||
_: CurrentUser = Depends(require_roles(ADMIN_ROLES)),
|
||||
repository: BackendRepository = Depends(get_repository),
|
||||
) -> AgentJobResponse:
|
||||
try:
|
||||
return cancel_agent_job(repository, job_id)
|
||||
except LookupError as error:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not Found") from error
|
||||
|
||||
|
||||
@internal_router.post("/claim", response_model=None)
|
||||
def post_claim_agent_job(
|
||||
repository: BackendRepository = Depends(get_repository),
|
||||
):
|
||||
claimed = claim_next_agent_job(repository)
|
||||
if claimed is None:
|
||||
return Response(status_code=status.HTTP_204_NO_CONTENT)
|
||||
return claimed
|
||||
|
||||
|
||||
@internal_router.post("/{job_id}/complete", response_model=AgentJobResponse)
|
||||
def post_complete_agent_job(
|
||||
job_id: UUID,
|
||||
request: AgentJobCompletionRequest,
|
||||
repository: BackendRepository = Depends(get_repository),
|
||||
) -> AgentJobResponse:
|
||||
try:
|
||||
return complete_agent_job(
|
||||
repository,
|
||||
job_id=job_id,
|
||||
workspace_path=request.workspace_path,
|
||||
stdout=request.stdout,
|
||||
stderr=request.stderr,
|
||||
exit_code=request.exit_code,
|
||||
duration_ms=request.duration_ms,
|
||||
output=request.output,
|
||||
)
|
||||
except LookupError as error:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not Found") from error
|
||||
Reference in New Issue
Block a user