From 029402a620d47c363202b78242ec5d0fea9395b0 Mon Sep 17 00:00:00 2001 From: mstfyldz Date: Mon, 10 Aug 2026 00:35:00 +0300 Subject: [PATCH] fix: raise num_predict for interactive chat to stop mid-sentence cutoffs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 800 token sınırı çok düşüktü — çok bölümlü hukuki cevaplar (kira feshi, tazminat hesabı gibi) bu sınıra çarpıp cümlenin ortasında kesiliyordu. Varsayılan ve chatMessage/sendThreadMessage'ın kullandığı num_predict 2048'e çıkarıldı. Ayrıca Ollama done_reason:"length" döndürdüğünde (yanıt sınıra çarpıp kesildiğinde) sunucu loglarına uyarı yazılıyor. Co-Authored-By: Claude Sonnet 5 --- src/controllers/chat.controller.ts | 4 ++-- src/lib/aiClient.ts | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/controllers/chat.controller.ts b/src/controllers/chat.controller.ts index 6d1f3cf..b4f28e7 100644 --- a/src/controllers/chat.controller.ts +++ b/src/controllers/chat.controller.ts @@ -122,7 +122,7 @@ export const chatMessage = async (req: AuthenticatedRequest, res: Response) => { } startSse(res); - const aiContent = await streamOllama(messages, (delta) => sseWrite(res, { delta }), { numPredict: 800 }); + const aiContent = await streamOllama(messages, (delta) => sseWrite(res, { delta }), { numPredict: 2048 }); const { data: aiMessage, error: aiMsgError } = await supabase .from('chat_messages') @@ -207,7 +207,7 @@ export const sendThreadMessage = async (req: AuthenticatedRequest, res: Response } startSse(res); - const aiContent = await streamOllama(messages, (delta) => sseWrite(res, { delta }), { numPredict: 800 }); + const aiContent = await streamOllama(messages, (delta) => sseWrite(res, { delta }), { numPredict: 2048 }); const { data: aiMessage, error: aiMsgError } = await supabase .from('thread_messages') diff --git a/src/lib/aiClient.ts b/src/lib/aiClient.ts index a79a72f..1e40bea 100644 --- a/src/lib/aiClient.ts +++ b/src/lib/aiClient.ts @@ -6,7 +6,10 @@ export interface ChatMsg { role: string; content: string; } // davranışı: 5 dakika kullanılmazsa boşalır, sıradaki istek soğuk başlangıç // gecikmesi yaşar) worker'ı bu süre boyunca bellekte tutmasını istiyoruz. const KEEP_ALIVE = '30m'; -const DEFAULT_NUM_PREDICT = 800; +// 800 pratikte çok düşük çıktı — çok bölümlü hukuki cevaplar (kira feshi, tazminat +// hesabı gibi) bu sınıra çarpıp cümlenin ortasında kesiliyordu. 2048 hem çoğu cevabı +// tam bitirmeye yetiyor hem de modelin sonsuz uzayıp gitmesine karşı hâlâ bir üst sınır. +const DEFAULT_NUM_PREDICT = 2048; const DEFAULT_TIMEOUT_MS = 90_000; const DEFAULT_STALL_TIMEOUT_MS = 60_000; @@ -104,6 +107,12 @@ export async function streamOllama( full += delta; onToken(delta); } + // Ollama son satırda done_reason:"length" döndürürse yanıt num_predict + // sınırına çarpıp yarım kesilmiş demektir — sessizce geçmek yerine loglayıp + // ileride benzer bir "cevaplar yarım kalıyor" şikayetini hızlı teşhis edebilelim. + if (json.done && json.done_reason === 'length') { + console.warn('[aiClient] Yanıt num_predict sınırına çarpıp kesildi.'); + } }; while (true) {