From 0e572c3e415dd11eb9b3fa0a286c17edb4051f06 Mon Sep 17 00:00:00 2001 From: Leo Date: Mon, 22 Apr 2024 02:50:48 +0800 Subject: [PATCH] feat: support tls. #1234 (#1248) * feat: support tls. * update the frontend README. * Update frontend/README.md Co-authored-by: Boxuan Li --------- Co-authored-by: Boxuan Li --- Makefile | 2 +- frontend/.env | 6 ++- frontend/README.md | 24 +++++++----- frontend/vite.config.ts | 79 +++++++++++++++++++++++--------------- opendevin/server/listen.py | 6 +-- 5 files changed, 69 insertions(+), 48 deletions(-) diff --git a/Makefile b/Makefile index fca4df539f..586c2ab38a 100644 --- a/Makefile +++ b/Makefile @@ -122,7 +122,7 @@ start-backend: # Start frontend start-frontend: @echo "$(YELLOW)Starting frontend...$(RESET)" - @cd frontend && BACKEND_HOST=$(BACKEND_HOST) FRONTEND_PORT=$(FRONTEND_PORT) npm run start + @cd frontend && VITE_BACKEND_HOST=$(BACKEND_HOST) VITE_FRONTEND_PORT=$(FRONTEND_PORT) npm run start # Run the app run: diff --git a/frontend/.env b/frontend/.env index 8fecc59f85..ed87cc3840 100644 --- a/frontend/.env +++ b/frontend/.env @@ -1,2 +1,4 @@ -VITE_URL="http://localhost:3000" -VITE_WS_URL="ws://localhost:3000/ws" \ No newline at end of file +VITE_BACKEND_HOST="127.0.0.1:3000" +VITE_USE_TLS="false" +VITE_INSECURE_SKIP_VERIFY="false" +VITE_FRONTEND_PORT="3001" \ No newline at end of file diff --git a/frontend/README.md b/frontend/README.md index ca2be99516..9732df60b5 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -4,10 +4,10 @@ In the project directory, you can run: -### `npm start` +### `npm run start -- --port 3001` Runs the app in the development mode.\ -Open [http://localhost:3000](http://localhost:3000) to view it in the browser. +Open [http://localhost:3001](http://localhost:3001) to view it in the browser. The page will reload if you make edits.\ You will also see any lint errors in the console. @@ -20,16 +20,20 @@ It correctly bundles React in production mode and optimizes the build for the be The build is minified and the filenames include the hashes.\ Your app is ready to be deployed! +## Environment Variables +You can set the environment variables in `frontend/.env` to configure the frontend. The following variables are available: +```javascript +VITE_BACKEND_HOST="127.0.0.1:3000" // The host of the backend +VITE_USE_TLS="false" // Whether to use TLS for the backend(includes HTTPS and WSS) +VITE_INSECURE_SKIP_VERIFY="false" // Whether to skip verifying the backend's certificate. Only takes effect if `VITE_USE_TLS` is true. Don't use this in production! +VITE_FRONTEND_PORT="3001" // The port of the frontend +``` +You can also set the environment variables from outside the project, like `exporter VITE_BACKEND_HOST="127.0.0.1:3000"`. + +The outside environment variables will override the ones in the `.env` file. + ## Learn More You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). To learn React, check out the [React documentation](https://reactjs.org/). - -## Terminal - -The OpenDevin terminal is powered by [Xterm.js](https://github.com/xtermjs/xterm.js). - -The terminal listens for events over a WebSocket connection. The WebSocket URL is specified by the environment variable `VITE_WS_URL` (prepending `VITE_` to environment variable names is necessary to expose them). - -A simple websocket server can be found in the `/server` directory. diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index d6cec1167b..cf36af6b08 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -1,40 +1,57 @@ /// -import { defineConfig } from "vite"; +import { defineConfig, loadEnv } from "vite"; import react from "@vitejs/plugin-react"; import viteTsconfigPaths from "vite-tsconfig-paths"; -const BACKEND_HOST = process.env.BACKEND_HOST || "127.0.0.1:3000"; +export default defineConfig(({ mode }) => { + const { + VITE_BACKEND_HOST = "127.0.0.1:3000", + VITE_USE_TLS = "false", + VITE_FRONTEND_PORT = "3001", + VITE_INSECURE_SKIP_VERIFY = "false", + } = loadEnv(mode, process.cwd()); -// check BACKEND_HOST is something like "example.com" -if (!BACKEND_HOST.match(/^([\w\d-]+(\.[\w\d-]+)+(:\d+)?)/)) { - throw new Error( - `Invalid BACKEND_HOST ${BACKEND_HOST}, example BACKEND_HOST 127.0.0.1:3000`, - ); -} + const USE_TLS = VITE_USE_TLS === "true"; + const INSECURE_SKIP_VERIFY = VITE_INSECURE_SKIP_VERIFY === "true"; + const PROTOCOL = USE_TLS ? "https" : "http"; + const WS_PROTOCOL = USE_TLS ? "wss" : "ws"; -export default defineConfig({ - // depending on your application, base can also be "/" - base: "", - plugins: [react(), viteTsconfigPaths()], - clearScreen: false, - server: { - port: process.env.FRONTEND_PORT - ? Number.parseInt(process.env.FRONTEND_PORT, 10) - : 3001, - proxy: { - "/api": { - target: `http://${BACKEND_HOST}/`, - changeOrigin: true, - }, - "/ws": { - target: `ws://${BACKEND_HOST}/`, - ws: true, + const API_URL = `${PROTOCOL}://${VITE_BACKEND_HOST}/`; + const WS_URL = `${WS_PROTOCOL}://${VITE_BACKEND_HOST}/`; + const FE_PORT = Number.parseInt(VITE_FRONTEND_PORT, 10); + + // check BACKEND_HOST is something like "example.com" + if (!VITE_BACKEND_HOST.match(/^([\w\d-]+(\.[\w\d-]+)+(:\d+)?)/)) { + throw new Error( + `Invalid BACKEND_HOST ${VITE_BACKEND_HOST}, example BACKEND_HOST 127.0.0.1:3000`, + ); + } + + return { + // depending on your application, base can also be "/" + base: "", + plugins: [react(), viteTsconfigPaths()], + clearScreen: false, + server: { + port: FE_PORT, + proxy: { + "/api": { + target: API_URL, + changeOrigin: true, + secure: !INSECURE_SKIP_VERIFY, + }, + "/ws": { + target: WS_URL, + ws: true, + changeOrigin: true, + secure: !INSECURE_SKIP_VERIFY, + }, }, }, - }, - test: { - environment: "jsdom", - globals: true, - setupFiles: ["vitest.setup.ts"], - }, + test: { + environment: "jsdom", + globals: true, + setupFiles: ["vitest.setup.ts"], + }, + }; }); diff --git a/opendevin/server/listen.py b/opendevin/server/listen.py index 5f79f1239b..f67b8cc05e 100644 --- a/opendevin/server/listen.py +++ b/opendevin/server/listen.py @@ -38,17 +38,15 @@ async def websocket_endpoint(websocket: WebSocket): logger.error('Failed to decode token') return session_manager.add_session(sid, websocket) - # TODO: actually the agent_manager is created for each websocket connection, even if the session id is the same, - # we need to manage the agent in memory for reconnecting the same session id to the same agent agent_manager.register_agent(sid) await session_manager.loop_recv(sid, agent_manager.dispatch) @app.get('/api/litellm-models') async def get_litellm_models(): - ''' + """ Get all models supported by LiteLLM. - ''' + """ return list(set(litellm.model_list + list(litellm.model_cost.keys())))