diff --git a/server.js b/server.js index fd0ed5b..04e34b5 100644 --- a/server.js +++ b/server.js @@ -6208,7 +6208,13 @@ wss.on('connection', async (socket, req) => { // ── Chat via WebSocket (TUI Gateway) ── if (msg.type === 'chat.start' && socket.authed) { console.log(`[WS] chat.start received profile="${msg.profile || 'default'}" session_id="${msg.session_id || 'null'}"`); - const bridge = getBridge(msg.profile || 'default'); + const profileName = msg.profile || 'default'; + if (socket.tuiBridge && socket.tuiBridge.profile !== profileName) { + socket.tuiBridge.removeClient(socket); + socket.tuiBridge = null; + socket.tuiSessionId = undefined; + } + const bridge = getBridge(profileName); if (!bridge.proc) { let startErr = null; for (let attempt = 1; attempt <= 3; attempt++) { @@ -6239,14 +6245,50 @@ wss.on('connection', async (socket, req) => { } } if (msg.type === 'chat.stop' && socket.authed && socket.tuiBridge) { - socket.tuiBridge.chatStop(socket.tuiSessionId); + socket.tuiBridge.chatStop(msg.session_id || socket.tuiSessionId); } - if (msg.type === 'chat.send' && socket.authed && socket.tuiBridge) { + if (msg.type === 'chat.send' && socket.authed) { try { - // Use frontend's session_id if provided, else fall back to chat.start session - const sid = msg.session_id || socket.tuiSessionId; - if (msg.session_id) socket.tuiSessionId = msg.session_id; // update for future sends - await socket.tuiBridge.chatSend({ message: msg.message, session_id: sid }); + const profileName = msg.profile || 'default'; + if (socket.tuiBridge && socket.tuiBridge.profile !== profileName) { + socket.tuiBridge.removeClient(socket); + socket.tuiBridge = null; + socket.tuiSessionId = undefined; + } + if (!socket.tuiBridge) { + console.log(`[WS] chat.send bootstrapping bridge profile="${profileName}" session_id="${msg.session_id || 'null'}"`); + const bridge = getBridge(profileName); + if (!bridge.proc) { + let startErr = null; + for (let attempt = 1; attempt <= 3; attempt++) { + try { + await bridge.start(); + startErr = null; + break; + } catch (e) { + startErr = e; + console.error(`[WS] Bridge start attempt ${attempt}/3 failed:`, e.message); + if (attempt < 3) await new Promise(r => setTimeout(r, 500)); + } + } + if (startErr) { + socket.send(JSON.stringify({ type: 'chat.error', error: 'TUI gateway unavailable after 3 retries.' })); + return; + } + } + bridge.addClient(socket); + socket.tuiBridge = bridge; + } + if (msg.session_id && msg.session_id !== socket.tuiSessionId) { + const result = await socket.tuiBridge.chatStart({ + message: msg.message, + session_id: msg.session_id, + }); + socket.tuiSessionId = result.session_id; + } else { + const sid = msg.session_id || socket.tuiSessionId; + await socket.tuiBridge.chatSend({ message: msg.message, session_id: sid }); + } } catch (err) { socket.send(JSON.stringify({ type: 'chat.error', error: err.message })); } diff --git a/src/js/chat/websocket.js b/src/js/chat/websocket.js index 754f2ab..96ef64d 100644 --- a/src/js/chat/websocket.js +++ b/src/js/chat/websocket.js @@ -48,7 +48,7 @@ async function sendViaWebSocket(text, profile, sessionId) { // Send via WS — use chatStart for first message, chatSend for subsequent let ok; if (sessionId) { - ok = wsClient.chatSend({ message: text, session_id: sessionId }); + ok = wsClient.chatSend({ message: text, session_id: sessionId, profile }); } else { ok = wsClient.chatStart({ message: text, profile, session_id: sessionId }); } diff --git a/src/js/ws-client.js b/src/js/ws-client.js index fbc2495..8679b8e 100644 --- a/src/js/ws-client.js +++ b/src/js/ws-client.js @@ -89,8 +89,8 @@ class HciWsClient extends EventTarget { chatStart({ message, profile, session_id, model }) { return this.send({ type: 'chat.start', message, profile, session_id, model }); } - chatSend({ message, session_id }) { - return this.send({ type: 'chat.send', message, session_id }); + chatSend({ message, session_id, profile }) { + return this.send({ type: 'chat.send', message, session_id, profile }); } chatStop() { return this.send({ type: 'chat.stop' });