96 lines
3.5 KiB
TypeScript
96 lines
3.5 KiB
TypeScript
import { Response } from 'express';
|
||
import { supabase } from '../lib/supabase';
|
||
import { AuthenticatedRequest } from '../middleware/auth';
|
||
|
||
export const chatMessage = async (req: AuthenticatedRequest, res: Response) => {
|
||
try {
|
||
const { caseId } = req.params;
|
||
const { content } = req.body;
|
||
const userId = req.user?.id;
|
||
|
||
if (!content || !caseId) {
|
||
return res.status(400).json({ error: 'Missing caseId or content' });
|
||
}
|
||
|
||
const { data: userMessage, error: userMsgError } = await supabase
|
||
.from('chat_messages')
|
||
.insert([{ case_id: caseId, user_id: userId, role: 'user', content }])
|
||
.select().single();
|
||
if (userMsgError) throw userMsgError;
|
||
|
||
// 1. Dosyaya ait belge analizlerini çek (EKSİK OLAN KISIM)
|
||
const { data: analyses } = await supabase
|
||
.from('analyses')
|
||
.select('summary_json')
|
||
.eq('case_id', caseId);
|
||
|
||
const { data: documents } = await supabase
|
||
.from('documents')
|
||
.select('filename, extracted_text')
|
||
.eq('case_id', caseId);
|
||
|
||
// 2. Geçmiş sohbet
|
||
const { data: pastMessages } = await supabase
|
||
.from('chat_messages')
|
||
.select('role, content')
|
||
.eq('case_id', caseId)
|
||
.order('created_at', { ascending: true })
|
||
.limit(10);
|
||
|
||
// 3. Belge bağlamını sistem promptuna göm
|
||
let documentContext = '';
|
||
if (documents && documents.length > 0) {
|
||
documentContext = '\n\nDOSYAYA AİT BELGELER:\n' +
|
||
documents.map(d => `--- ${d.filename} ---\n${d.extracted_text}`).join('\n\n');
|
||
} else {
|
||
documentContext = '\n\nBu dosyaya henüz hiçbir belge yüklenmemiştir. Genel hukuki bilgiyle cevap ver, ama bunu kullanıcıya açıkça belirt.';
|
||
}
|
||
|
||
if (analyses && analyses.length > 0) {
|
||
documentContext += '\n\nÖNCEKİ ANALİZ ÖZETİ:\n' + JSON.stringify(analyses[analyses.length - 1].summary_json);
|
||
}
|
||
|
||
const systemPrompt = `Sen bir hukuk asistanısın. Bu dava dosyasıyla ilgili kullanıcının sorularını, aşağıda verilen belge içeriğine dayanarak cevaplıyorsun. Eğer belge yoksa veya soruyu cevaplamaya yetmiyorsa, bunu açıkça belirt, uydurma bilgi verme.${documentContext}`;
|
||
|
||
const messages: any[] = [{ role: 'system', content: systemPrompt }];
|
||
if (pastMessages) {
|
||
pastMessages.forEach(m => messages.push({ role: m.role, content: m.content }));
|
||
} else {
|
||
messages.push({ role: 'user', content });
|
||
}
|
||
|
||
const aiModel = process.env.AI_MODEL || 'mizan-fixed';
|
||
// Native endpoint'e geçiş
|
||
const runpodUrl = process.env.RUNPOD_API_BASE_URL || 'https://q190env94stwis-11434.proxy.runpod.net';
|
||
|
||
const response = await fetch(`${runpodUrl}/api/chat`, {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({
|
||
model: aiModel,
|
||
messages: messages,
|
||
think: false,
|
||
stream: false,
|
||
}),
|
||
});
|
||
|
||
if (!response.ok) {
|
||
throw new Error(`AI Model request failed: ${response.statusText}`);
|
||
}
|
||
|
||
const data = await response.json();
|
||
const aiContent = data.message?.content || 'Yanıt alınamadı.';
|
||
|
||
const { data: aiMessage, error: aiMsgError } = await supabase
|
||
.from('chat_messages')
|
||
.insert([{ case_id: caseId, user_id: userId, role: 'assistant', content: aiContent }])
|
||
.select().single();
|
||
if (aiMsgError) throw aiMsgError;
|
||
|
||
res.json({ message: aiMessage });
|
||
} catch (error: any) {
|
||
console.error('Chat Error:', error);
|
||
res.status(500).json({ error: error.message || 'Internal Server Error' });
|
||
}
|
||
};
|