feat(sohbet): rehber bağlantıları akışta gerçek slug'larla doğrulanıyor

Model araç çağırmadan ezberden /rehber/<slug> yazabiliyordu; istemci her
adresi "Rehber yazısı" hapı yapıp 404'e gönderiyordu. Yeni saf modül
lib/ai/baglanti-denetimi.ts: kayıtlı slug dokunulmaz, yakın slug (Dice ≥ 0,5
ve açık ara önde) kayıttaki başlıkla yeniden yazılır, uydurma slug düz metne
iner / çıplak adres silinir. BaglantiTamponu akış sırasında çalışır (cevap
bittikten sonra ekrandaki hap geri alınamaz); parça parça çıktı tek seferlik
sonuçla birebir aynı. danismanAkisi `rehberler` seçeneği alır (verilmezse
pasif); route gerçek content/rehber listesini verir; CiktiDenetimi'ne
baglantiDuzeltme eklendi. Prompt BAĞLANTI maddesi rehber_ara'yı teşvik eder.

Aynı dosyalardaki revizyon-hak metinleri (prompt revizyonBolumu, araç
açıklaması/HAK dalı, route'taki kalanHak/kalanRevizyon) de bu commit'te:
sınırın kaldırılması bir sonraki commit'te tamamlanır.

Test: scripts/eval/baglanti-denetim.ts (44/44) ve akis-denetim.ts'e
rehber-uydurma / rehber-gercek senaryoları (9/9).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
bilalgursen
2026-10-07 23:16:34 +03:00
parent 4d30dd1305
commit 15f4c4f4e1
7 changed files with 439 additions and 30 deletions

View File

@@ -22,8 +22,8 @@ import {
type RevizyonOzeti,
type SohbetMeta,
} from "@/lib/ai/sohbet-meta";
import { MAX_REVIZYON } from "@/lib/credits";
import { profilGetir } from "@/lib/danisman-profil-db";
import { getRehberAramaKayitlari } from "@/lib/rehber";
import { listeOzetiCikar } from "@/lib/ai/rapor";
import type { RaporSonuc } from "@/features/rapor/types/rapor";
import type { RaporParams } from "@/features/rapor/types/rapor";
@@ -196,7 +196,7 @@ export async function POST(request: NextRequest) {
uyarilar: raporSonuc.uyarilar,
kapsam: raporSonuc.kapsam ? { toplam: raporSonuc.kapsam.toplam, uyarlandi: raporSonuc.kapsam.uyarlandi } : undefined,
},
revizyon: { kalanHak: Math.max(0, MAX_REVIZYON - rapor.revisionCount), paketli },
revizyon: { paketli },
});
// Araçların bağlamı: aday sırası/puan türü (arama süzgeci), profil
// (profil_guncelle yazınca aynı tur içinde tazelenir) ve sihirbaz seçimleri
@@ -207,7 +207,6 @@ export async function POST(request: NextRequest) {
tur: raporParams.tur,
hasPaket: paketli,
mesajId: kullaniciMesajId,
kalanRevizyon: Math.max(0, MAX_REVIZYON - rapor.revisionCount),
profil,
oncelikler: raporParams.oncelikler ?? [],
ozelDurum: raporParams.ozelDurum ?? [],
@@ -297,6 +296,9 @@ export async function POST(request: NextRequest) {
system,
mesajlar,
aracBaglami,
// Cevaptaki /rehber/<slug> adresleri gerçek yazı listesiyle doğrulanır
// (prod'da cache'li, lib/rehber.ts)
rehberler: getRehberAramaKayitlari(),
onAracSonucu: (ad, cikti) => {
const c = cikti as Record<string, unknown>;
if (ad === "soru_sor" && c.anket) cevapMeta.anket = c.anket as SohbetMeta["anket"];