/** * Danışman sohbet geçmişinin saf kuralları (api/soru/route.ts kullanır). * * Saf modül: DB'ye ve oturuma dokunmaz, Next dışından da çalışır. */ export type SohbetMesaji = { role: "user" | "assistant"; content: string }; /** * Modele giden mesaj penceresi: kayıtlı geçmiş + yeni soru. Kayıt her zaman * soru-cevap çifti değildir — hata/iade sonrası kullanıcı mesajı cevapsız * kalır, pencere de sayıyla kesildiği için danışman mesajıyla başlayabilir. * Burada düzeltilir: baştaki danışman mesajları atılır, art arda aynı rolden * gelenler tek mesajda birleşir (yinelenen metin bir kez yazılır). Sonuç * hep user ile başlar, roller sırayla değişir ve yeni soruyla biter. */ export function modelPenceresi(gecmis: SohbetMesaji[], yeniSoru: string): SohbetMesaji[] { const gruplar: { role: SohbetMesaji["role"]; parcalar: string[] }[] = []; for (const m of [...gecmis, { role: "user" as const, content: yeniSoru }]) { const son = gruplar.at(-1); if (!son && m.role === "assistant") continue; if (son?.role === m.role) { if (!son.parcalar.includes(m.content)) son.parcalar.push(m.content); } else { gruplar.push({ role: m.role, parcalar: [m.content] }); } } return gruplar.map((g) => ({ role: g.role, content: g.parcalar.join("\n\n") })); } /** Danışmanın onay sorusunda geçen sabit ibare; istemci de bunu görmez, yalnız sunucu arar. */ const ONAY_SORUSU = "profiline kaydedeyim mi"; const ONAY_SOZLERI = [ "evet", "olur", "tamam", "kaydet", "kaydedebilirsin", "kaydedelim", "hayır", "hayir", "yok", "kaydetme", "gerek yok", "istemiyorum", "şimdilik hayır", ]; /** Onay sözünün ardından gelebilecek dolgu; bunların dışındaki her kelime mesajı soru yapar. */ const ONAY_DOLGU = [...ONAY_SOZLERI, "bunu", "lütfen", "lutfen", "teşekkürler", "tesekkurler", "teşekkür ederim", "sağ ol"]; const ONAY_KALIBI = new RegExp(`^(?:${ONAY_SOZLERI.join("|")})(?: (?:${ONAY_DOLGU.join("|")}))*$`); /** * Onay mesajı mı: son danışman mesajı "kaydedeyim mi?" diye sormuş VE adayın * mesajı BAŞTAN SONA evet/hayır sözlerinden oluşuyor. Bu mesaj kredi harcamaz * (Bilal, 26 Eyl 2026). Yalnız başına bakmak yetmiyordu: "evet. Ege hukuk * taban sırası kaç?" kredisiz tam cevap alıyordu. Kalıba uymayan mesaj * normal (kredili) soru sayılır. */ export function onayMesajiMi(mesaj: string, sonAsistan: string | undefined): boolean { if (!sonAsistan || !sonAsistan.toLocaleLowerCase("tr-TR").includes(ONAY_SORUSU)) return false; const m = mesaj .toLocaleLowerCase("tr-TR") .replace(/[.,!?;:…'"()]+/g, " ") .replace(/\s+/g, " ") .trim(); return ONAY_KALIBI.test(m); }