High-level shape
Browser → Caddy (HTTPS) → FastAPI (uvicorn)
├── REST API
├── WebSocket
└── Static frontend assets
Backend
Key backend files:
backend/server.py— FastAPI app, WebSocket handler, REST API, static file servingbackend/agents.py— agent configuration, model fallback, system promptsbackend/tools.py— bash, file, search, and web toolsbackend/context.py— injects project context such asAGENTS.mdand directory treebackend/compact.py— summarizes older messages when context gets largebackend/storage.py— flat-file persistence for projects and conversationsbackend/models.py— Pydantic models for REST APIbackend/protocol.py— WebSocket event models
Frontend
Key frontend files:
frontend/src/main.tsx— app entry, routing, auth gatefrontend/src/api.ts— REST and WebSocket clientfrontend/src/views/Chat.tsx— main chat UIfrontend/src/views/ProjectList.tsx— project list pagefrontend/src/views/ConvoList.tsx— conversation list pagefrontend/src/components/FilePanel.tsx— side panel for viewing and editing filesfrontend/src/components/CodeMirrorEditor.tsx— full editor, lazy-loadedfrontend/src/components/FileFinder.tsx— file finder modal
Persistence model
Remote Lab uses JSON files on disk instead of a database.
data/
projects.json
conversations/{id}.meta.json
conversations/{id}.jsonl
conversations/{id}.agent.json
This keeps the system easy to inspect, back up, and modify.
Execution model
A key design choice is that agent runs are decoupled from the browser connection.
The backend runs agent work as an async task. If the browser disconnects, the task can keep running. When the client reconnects, it receives the persisted history and any new streamed events.
Context management
When a conversation approaches the model context limit, older messages are compacted into a summary. This preserves continuity without sending the full raw history on every turn.
Project scoping
Each project points to a real directory on disk. Agent tools run relative to that directory and are sandboxed to it.