gemini-agent / src /interface /api /routes.py
likhon saheikh
Deploy full Gemini Agentic Platform
ad8ba8a
Raw
History Blame Contribute Delete
5.46 kB
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
@router.put("/sessions", response_model=StandardResponse)
async def create_session():
session = await session_manager.create_new_session()
return {"code": 0, "msg": "success", "data": {"session_id": session.session_id}}
@router.get("/sessions/{session_id}", response_model=StandardResponse)
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": []}}
@router.get("/sessions", response_model=StandardResponse)
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}}
@router.delete("/sessions/{session_id}", response_model=StandardResponse)
async def delete_session(session_id: str):
await session_manager.delete_session(session_id)
return {"code": 0, "msg": "success", "data": None}
@router.post("/sessions/{session_id}/stop", response_model=StandardResponse)
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)
@router.post("/sessions/{session_id}/chat")
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
@router.post("/sessions/{session_id}/shell", response_model=StandardResponse)
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}]
}
}
@router.post("/sessions/{session_id}/file", response_model=StandardResponse)
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
@router.websocket("/sessions/{session_id}/vnc")
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()