# -*- coding: utf-8 -*- """ Workspace API Routes. These routes manage the design-time `workspaces/` registry, not the run-scoped runtime data under `runs//`. """ from typing import Any, Dict, List, Optional from fastapi import APIRouter, HTTPException, Depends from pydantic import BaseModel, Field from backend.agents import WorkspaceManager router = APIRouter(prefix="/api/workspaces", tags=["workspaces"]) # Request/Response Models class CreateWorkspaceRequest(BaseModel): """Request to create a new workspace.""" workspace_id: str = Field(..., description="Unique workspace identifier") name: Optional[str] = Field(None, description="Display name") description: Optional[str] = Field(None, description="Workspace description") metadata: Optional[Dict[str, Any]] = Field(None, description="Additional metadata") class UpdateWorkspaceRequest(BaseModel): """Request to update a workspace.""" name: Optional[str] = None description: Optional[str] = None metadata: Optional[Dict[str, Any]] = None class WorkspaceResponse(BaseModel): """Design-time workspace information response.""" workspace_id: str name: str description: str created_at: Optional[str] = None metadata: Dict[str, Any] = Field(default_factory=dict) class WorkspaceListResponse(BaseModel): """List of workspaces response.""" workspaces: List[WorkspaceResponse] total: int # Dependencies def get_workspace_manager(): """Get WorkspaceManager instance.""" return WorkspaceManager() # Routes @router.post("", response_model=WorkspaceResponse) async def create_workspace( request: CreateWorkspaceRequest, manager: WorkspaceManager = Depends(get_workspace_manager), ): """ Create a new workspace. Args: request: Workspace creation parameters Returns: Created workspace information """ try: config = manager.create_workspace( workspace_id=request.workspace_id, name=request.name, description=request.description, metadata=request.metadata or {}, ) return WorkspaceResponse( workspace_id=config.workspace_id, name=config.name, description=config.description, created_at=config.created_at, metadata=config.metadata, ) except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) @router.get("", response_model=WorkspaceListResponse) async def list_workspaces( manager: WorkspaceManager = Depends(get_workspace_manager), ): """ List all design-time workspaces. Returns: List of design-time workspaces """ workspaces = manager.list_workspaces() return WorkspaceListResponse( workspaces=[ WorkspaceResponse( workspace_id=ws.workspace_id, name=ws.name, description=ws.description, created_at=ws.created_at, metadata=ws.metadata, ) for ws in workspaces ], total=len(workspaces), ) @router.get("/{workspace_id}", response_model=WorkspaceResponse) async def get_workspace( workspace_id: str, manager: WorkspaceManager = Depends(get_workspace_manager), ): """ Get workspace details. Args: workspace_id: Workspace identifier Returns: Workspace information """ workspace = manager.get_workspace(workspace_id) if not workspace: raise HTTPException(status_code=404, detail=f"Workspace '{workspace_id}' not found") return WorkspaceResponse( workspace_id=workspace["workspace_id"], name=workspace.get("name", workspace_id), description=workspace.get("description", ""), created_at=workspace.get("created_at"), metadata=workspace.get("metadata", {}), ) @router.patch("/{workspace_id}", response_model=WorkspaceResponse) async def update_workspace( workspace_id: str, request: UpdateWorkspaceRequest, manager: WorkspaceManager = Depends(get_workspace_manager), ): """ Update workspace configuration. Args: workspace_id: Workspace identifier request: Update parameters Returns: Updated workspace information """ try: config = manager.update_workspace_config( workspace_id=workspace_id, name=request.name, description=request.description, metadata=request.metadata, ) return WorkspaceResponse( workspace_id=config.workspace_id, name=config.name, description=config.description, created_at=config.created_at, metadata=config.metadata, ) except ValueError as e: raise HTTPException(status_code=404, detail=str(e)) @router.delete("/{workspace_id}") async def delete_workspace( workspace_id: str, force: bool = False, manager: WorkspaceManager = Depends(get_workspace_manager), ): """ Delete a workspace. Args: workspace_id: Workspace identifier force: If True, delete even if workspace has agents Returns: Success message """ try: success = manager.delete_workspace(workspace_id, force=force) if not success: raise HTTPException(status_code=404, detail=f"Workspace '{workspace_id}' not found") return {"message": f"Workspace '{workspace_id}' deleted successfully"} except ValueError as e: raise HTTPException(status_code=400, detail=str(e))