Spaces:
Build error
Build error
| from fastapi import APIRouter, HTTPException, BackgroundTasks | |
| from typing import List, Optional | |
| from pydantic import BaseModel | |
| router = APIRouter() | |
| from src.domain.models import ( | |
| StandardResponse, SessionResponse, SessionDetailResponse, | |
| ChatRequest, ShellRequest, FileRequest, ShellResponse, FileResponse | |
| ) | |
| # --- Endpoints --- | |
| from src.application.session_manager import session_manager | |
| async def create_session(): | |
| session = await session_manager.create_new_session() | |
| return {"code": 0, "msg": "success", "data": {"session_id": session.session_id}} | |
| async def get_session(session_id: str): | |
| session = await session_manager.get_session_details(session_id) | |
| if not session: | |
| return {"code": 404, "msg": "Session not found", "data": None} | |
| return {"code": 0, "msg": "success", "data": {"session_id": session.session_id, "title": session.title, "events": []}} | |
| async def list_sessions(): | |
| sessions = await session_manager.list_all_sessions() | |
| session_list = [ | |
| { | |
| "session_id": s.session_id, | |
| "title": s.title, | |
| "latest_message": s.messages[-1].content if s.messages else "", | |
| "latest_message_at": s.messages[-1].timestamp if s.messages else s.updated_at, | |
| "status": s.status, | |
| "unread_message_count": 0 | |
| } | |
| for s in sessions | |
| ] | |
| return {"code": 0, "msg": "success", "data": {"sessions": session_list}} | |
| async def delete_session(session_id: str): | |
| await session_manager.delete_session(session_id) | |
| return {"code": 0, "msg": "success", "data": None} | |
| async def stop_session(session_id: str): | |
| await session_manager.stop_session(session_id) | |
| return {"code": 0, "msg": "success", "data": None} | |
| from fastapi.responses import StreamingResponse | |
| from src.application.chat_service import ChatService | |
| from src.infrastructure.llm.gemini_client import GeminiAgent | |
| import os | |
| import json | |
| # Initialize services (Dependency Injection would be better in production) | |
| api_key = os.getenv("GEMINI_API_KEY") | |
| gemini_agent = GeminiAgent(api_key=api_key) | |
| chat_service = ChatService(session_manager, gemini_agent) | |
| async def chat_session(session_id: str, request: ChatRequest): | |
| async def event_generator(): | |
| async for event in chat_service.chat(session_id, request.message): | |
| # Format as SSE | |
| yield f"event: {event['event']}\ndata: {json.dumps(event['data'])}\n\n" | |
| return StreamingResponse(event_generator(), media_type="text/event-stream") | |
| from src.infrastructure.sandbox.docker_manager import docker_sandbox | |
| async def view_shell(session_id: str, request: ShellRequest): | |
| if not docker_sandbox: | |
| return {"code": 500, "msg": "Sandbox service unavailable", "data": None} | |
| # In a real scenario, we might want to execute a command or get logs | |
| # For this API endpoint "view shell session content", it implies getting history | |
| # But the request body has "session_id" (shell session id). | |
| # For simplicity, we'll just return a mock or the last command output if we tracked it. | |
| # Let's assume we execute a 'whoami' just to prove it works, or return empty if no command provided. | |
| # Since the API spec says "View shell session output", let's assume we are retrieving logs | |
| # But our simple sandbox doesn't track shell sessions persistently yet. | |
| # We will return a placeholder or execute a dummy command to verify connectivity. | |
| output = await docker_sandbox.execute_shell(session_id, "echo 'Shell session active'") | |
| return { | |
| "code": 0, | |
| "msg": "success", | |
| "data": { | |
| "output": output, | |
| "session_id": request.session_id, | |
| "console": [{"ps1": "$", "command": "echo 'Shell session active'", "output": output}] | |
| } | |
| } | |
| async def view_file(session_id: str, request: FileRequest): | |
| if not docker_sandbox: | |
| return {"code": 500, "msg": "Sandbox service unavailable", "data": None} | |
| content = await docker_sandbox.read_file(session_id, request.file) | |
| return {"code": 0, "msg": "success", "data": {"content": content, "file": request.file}} | |
| from fastapi import WebSocket, WebSocketDisconnect | |
| async def vnc_websocket(websocket: WebSocket, session_id: str): | |
| await websocket.accept(subprotocol="binary") | |
| try: | |
| # In a real implementation, we would connect to the VNC port of the container | |
| # and proxy the traffic. | |
| # For now, we just keep the connection open and echo back any data or send a placeholder. | |
| while True: | |
| data = await websocket.receive_bytes() | |
| # Echo or process | |
| await websocket.send_bytes(data) | |
| except WebSocketDisconnect: | |
| print(f"VNC Client disconnected for session {session_id}") | |
| except Exception as e: | |
| print(f"VNC Error: {e}") | |
| await websocket.close() | |