Onay mesajı artık baştan sona evet/hayır sözlerinden oluşmalı; "evet. <gerçek soru>" normal (kredili) soru sayılır, 0 kredide 402 döner. "Profil onayı kredi harcamaz" kararı (26 Eyl) gerçek onay için aynen duruyor. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
69 lines
2.7 KiB
TypeScript
69 lines
2.7 KiB
TypeScript
/**
|
||
* 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);
|
||
}
|