diff --git a/.changeset/fix-ws-origin-dev-proxy.md b/.changeset/fix-ws-origin-dev-proxy.md new file mode 100644 index 000000000..c54f21d64 --- /dev/null +++ b/.changeset/fix-ws-origin-dev-proxy.md @@ -0,0 +1,5 @@ +--- +"@moonshot-ai/kimi-code": patch +--- + +Fix WebSocket connection failures in the bundled web UI's local dev mode when the browser opens on `localhost` while the server binds `127.0.0.1`. diff --git a/apps/kimi-web/vite.config.ts b/apps/kimi-web/vite.config.ts index 0bc8a10a0..2c9a6a593 100644 --- a/apps/kimi-web/vite.config.ts +++ b/apps/kimi-web/vite.config.ts @@ -11,6 +11,18 @@ const pkg = JSON.parse(readFileSync(new URL('./package.json', import.meta.url), version: string; }; +function apiProxyConfig() { + return { + target: serverTarget, + changeOrigin: true, + ws: true, + // Rewrite the WebSocket Origin header to the upstream target so the + // server's same-origin check passes even when the browser opens the dev UI + // on `localhost:5175` while the server binds `127.0.0.1`. + rewriteWsOrigin: true, + }; +} + export default defineConfig({ plugins: [vue(), tailwindcss()], // Expose the dev proxy's upstream server target to the client so the UI can @@ -26,7 +38,7 @@ export default defineConfig({ // Same-origin dev: the browser calls Vite, Vite forwards to the server. // No CORS anywhere. The real server serves REST + WS all under /api/v1. proxy: { - '/api/v1': { target: serverTarget, changeOrigin: true, ws: true }, + '/api/v1': apiProxyConfig(), }, }, // `vite preview` (the production build served locally) needs the same proxy — @@ -35,7 +47,7 @@ export default defineConfig({ preview: { port: Number(process.env.WEB_PREVIEW_PORT) || 4175, proxy: { - '/api/v1': { target: serverTarget, changeOrigin: true, ws: true }, + '/api/v1': apiProxyConfig(), }, }, build: {