import { WebSocket } from 'ws'; import { randomUUID } from 'crypto'; import { getDb } from '../db'; import { runAgentChat } from '../agent/pi-bridge'; export function handleChat(ws: WebSocket) { let conversationId: string | null = null; ws.on('message', async (raw) => { try { const msg = JSON.parse(raw.toString()); if (msg.type === 'init') { conversationId = msg.conversationId || randomUUID(); const history = getDb().prepare( 'SELECT * FROM messages WHERE conversation_id = ? ORDER BY created_at' ).all(conversationId); ws.send(JSON.stringify({ type: 'history', data: { conversationId, messages: history } })); return; } if (msg.type === 'create_conversation') { const { title, accountId } = msg; conversationId = randomUUID(); getDb().prepare( 'INSERT INTO conversations (id, title, account_id) VALUES (?, ?, ?)' ).run(conversationId, title || '新对话', accountId || null); ws.send(JSON.stringify({ type: 'conversation_created', data: { id: conversationId, title } })); return; } if (msg.type === 'chat') { // Fallback: use conversationId from message if server state lost (e.g. after reconnect) if (!conversationId && msg.conversationId) { conversationId = msg.conversationId as string; } if (!conversationId) { ws.send(JSON.stringify({ type: 'error', data: { message: '没有活跃对话,请先创建或选择一个对话' } })); return; } await runAgentChat(ws, conversationId, msg.content, msg.images); } } catch (e) { console.error('WebSocket error:', e); ws.send(JSON.stringify({ type: 'error', data: { message: (e as Error).message } })); } }); ws.on('close', () => {}); }