fix(danisman): H2 (2) — zaman aşımında yarım cevap tamam sayılmasın, kredi iade edilsin
SDK akış ortası abort'u hata fırlatmadan "abort" parçasıyla bitiriyordu; döngü bunu tamamlanma sayıp yarım metni kaydediyor, krediyi iade etmiyordu. Döngüden sonra sinyale bakılır: kesildiyse onYarim (iade + yarım kayıt) çalışır, istemciye hata parçası gider. Süre zamanAsimiMs ile verilebilir (varsayılan 120 sn). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -34,6 +34,8 @@ export function danismanAkisi(opts: {
|
||||
onTamam: (metin: string) => Promise<void>;
|
||||
/** Cevap tamamlanamadı; `metin` o ana kadar üretilen kısım (boş olabilir). */
|
||||
onYarim: (metin: string) => Promise<void>;
|
||||
/** Sağlayıcı bu sürede bitirmezse cevap yarım sayılır (varsayılan 120 sn). */
|
||||
zamanAsimiMs?: number;
|
||||
}): ReadableStream<UIMessageChunk> {
|
||||
return createUIMessageStream<UIMessage>({
|
||||
execute: async ({ writer }) => {
|
||||
@@ -41,6 +43,9 @@ export function danismanAkisi(opts: {
|
||||
let metin = "";
|
||||
// Model/sağlayıcı hatası akışa "error" parçası olarak düşer
|
||||
let akisHatasi: string | null = null;
|
||||
// Sağlayıcı takılırsa SDK akışı "abort" parçasıyla sessizce bitirir
|
||||
// (hata fırlatmaz); döngüden sonra sinyale ayrıca bakılır.
|
||||
const zamanAsimi = AbortSignal.timeout(opts.zamanAsimiMs ?? 120_000);
|
||||
try {
|
||||
const result = streamText({
|
||||
model: sohbetDilModeli(),
|
||||
@@ -53,7 +58,7 @@ export function danismanAkisi(opts: {
|
||||
prepareStep: ({ stepNumber }) =>
|
||||
stepNumber >= ARAC_TUR_SINIRI - 1 ? { toolChoice: "none" } : undefined,
|
||||
maxOutputTokens: 1024,
|
||||
abortSignal: AbortSignal.timeout(120_000),
|
||||
abortSignal: zamanAsimi,
|
||||
providerOptions: { openaiCompatible: { reasoningEffort: "none" } },
|
||||
onError: ({ error }) => {
|
||||
// Hata nesnesinin tamamı istek gövdesini ve cevap başlıklarını
|
||||
@@ -71,6 +76,8 @@ export function danismanAkisi(opts: {
|
||||
for (;;) {
|
||||
const { done, value: parca } = await okuyucu.read();
|
||||
if (done) break;
|
||||
// Kesilme istemciye "abort" değil hata olarak gider (aşağıda fırlatılır)
|
||||
if (parca.type === "abort") continue;
|
||||
if (parca.type === "text-start" && metin && !metin.endsWith("\n")) {
|
||||
// Araç turundan sonra yeni metin parçası: kayıtta yapışmasın
|
||||
metin += "\n\n";
|
||||
@@ -82,6 +89,8 @@ export function danismanAkisi(opts: {
|
||||
writer.write(parca);
|
||||
}
|
||||
if (akisHatasi != null) throw new Error(akisHatasi);
|
||||
// Yarım metin "tamamlandı" diye kaydedilmesin: onYarim krediyi iade eder
|
||||
if (zamanAsimi.aborted) throw new Error("Zaman aşımı: sağlayıcı cevabı bitirmedi");
|
||||
if (!metin.trim()) throw new Error("Boş cevap");
|
||||
|
||||
// Çıktı denetimi (jev.ts): cevap garanti/olasılık dili içeriyorsa
|
||||
|
||||
Reference in New Issue
Block a user