2026-05-07 02:36:42 +08:00
|
|
|
import { WebSocket } from 'ws';
|
|
|
|
|
import { randomUUID } from 'crypto';
|
|
|
|
|
import { getDb } from '../db';
|
2026-05-08 01:43:33 +08:00
|
|
|
import { runAgentChat } from '../agent/pi-bridge';
|
2026-05-07 02:36:42 +08:00
|
|
|
|
|
|
|
|
export function handleChat(ws: WebSocket) {
|
|
|
|
|
let conversationId: string | null = null;
|
|
|
|
|
|
|
|
|
|
ws.on('message', async (raw) => {
|
|
|
|
|
try {
|
2026-05-07 04:09:00 +08:00
|
|
|
const msg = JSON.parse(raw.toString());
|
2026-05-07 02:36:42 +08:00
|
|
|
|
|
|
|
|
if (msg.type === 'init') {
|
|
|
|
|
conversationId = msg.conversationId || randomUUID();
|
|
|
|
|
const history = getDb().prepare(
|
|
|
|
|
'SELECT * FROM messages WHERE conversation_id = ? ORDER BY created_at'
|
2026-05-08 01:43:33 +08:00
|
|
|
).all(conversationId);
|
2026-05-07 02:36:42 +08:00
|
|
|
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 } }));
|
2026-05-07 03:22:15 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (msg.type === 'chat') {
|
2026-05-08 03:15:21 +08:00
|
|
|
// Fallback: use conversationId from message if server state lost (e.g. after reconnect)
|
|
|
|
|
if (!conversationId && msg.conversationId) {
|
|
|
|
|
conversationId = msg.conversationId as string;
|
|
|
|
|
}
|
2026-05-07 04:09:00 +08:00
|
|
|
if (!conversationId) {
|
|
|
|
|
ws.send(JSON.stringify({ type: 'error', data: { message: '没有活跃对话,请先创建或选择一个对话' } }));
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-05-08 02:18:50 +08:00
|
|
|
await runAgentChat(ws, conversationId, msg.content, msg.images);
|
2026-05-07 02:36:42 +08:00
|
|
|
}
|
|
|
|
|
} catch (e) {
|
2026-05-07 03:22:15 +08:00
|
|
|
console.error('WebSocket error:', e);
|
2026-05-07 02:36:42 +08:00
|
|
|
ws.send(JSON.stringify({ type: 'error', data: { message: (e as Error).message } }));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2026-05-07 03:22:15 +08:00
|
|
|
ws.on('close', () => {});
|
|
|
|
|
}
|