fix(danisman): M3 (7) — modele giden pencere tutarlı olsun
Cevapsız kalmış (iade edilmiş) sorular art arda user mesajı olarak, sayıyla kesilen pencere de danışman mesajıyla başlayarak gidiyordu. modelPenceresi baştaki danışman mesajlarını atar, art arda aynı rolü tek mesajda birleştirir. Pencere sorgusuna rowid sıralaması eklendi (created_at saniye çözünürlüklü). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { eq, desc } from "drizzle-orm";
|
||||
import { eq, desc, sql } from "drizzle-orm";
|
||||
import type { NextRequest } from "next/server";
|
||||
import { getSession } from "@/lib/session";
|
||||
import { appDb, schema } from "@/lib/appdb";
|
||||
@@ -14,6 +14,7 @@ import { kullanicininRaporu, sohbetGecmisiGetir } from "@/features/rapor/rapor-q
|
||||
import type { AracBaglami } from "@/lib/ai/araclar";
|
||||
import { danismanAkisi } from "@/lib/ai/sohbet-akisi";
|
||||
import { sistemPromptu } from "@/lib/ai/danisman-prompt";
|
||||
import { modelPenceresi } from "@/lib/ai/sohbet-gecmisi";
|
||||
import { profilGetir } from "@/lib/danisman-profil-db";
|
||||
import { listeOzetiCikar } from "@/lib/ai/rapor";
|
||||
import type { RaporSonuc } from "@/features/rapor/types/rapor";
|
||||
@@ -109,7 +110,7 @@ export async function POST(request: NextRequest) {
|
||||
.select()
|
||||
.from(schema.chatMessages)
|
||||
.where(eq(schema.chatMessages.userId, session.user.id))
|
||||
.orderBy(desc(schema.chatMessages.createdAt))
|
||||
.orderBy(desc(schema.chatMessages.createdAt), sql`rowid DESC`)
|
||||
.limit(MAX_GECMIS),
|
||||
appDb.query.user.findFirst({
|
||||
where: eq(schema.user.id, session.user.id),
|
||||
@@ -234,13 +235,9 @@ export async function POST(request: NextRequest) {
|
||||
);
|
||||
}
|
||||
|
||||
const mesajlar = [
|
||||
...gecmis.map((m) => ({
|
||||
role: m.role as "user" | "assistant",
|
||||
content: m.content,
|
||||
})),
|
||||
{ role: "user" as const, content: mesaj },
|
||||
];
|
||||
// Cevapsız kalmış (iade edilmiş) sorular ve danışmanla başlayan pencere
|
||||
// modele bozuk sıra göndermesin
|
||||
const mesajlar = modelPenceresi(gecmis, mesaj);
|
||||
|
||||
const userId = session.user.id;
|
||||
const cevabiKaydet = (metin: string) =>
|
||||
|
||||
29
src/lib/ai/sohbet-gecmisi.ts
Normal file
29
src/lib/ai/sohbet-gecmisi.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* 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") }));
|
||||
}
|
||||
Reference in New Issue
Block a user