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>;
|
onTamam: (metin: string) => Promise<void>;
|
||||||
/** Cevap tamamlanamadı; `metin` o ana kadar üretilen kısım (boş olabilir). */
|
/** Cevap tamamlanamadı; `metin` o ana kadar üretilen kısım (boş olabilir). */
|
||||||
onYarim: (metin: string) => Promise<void>;
|
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> {
|
}): ReadableStream<UIMessageChunk> {
|
||||||
return createUIMessageStream<UIMessage>({
|
return createUIMessageStream<UIMessage>({
|
||||||
execute: async ({ writer }) => {
|
execute: async ({ writer }) => {
|
||||||
@@ -41,6 +43,9 @@ export function danismanAkisi(opts: {
|
|||||||
let metin = "";
|
let metin = "";
|
||||||
// Model/sağlayıcı hatası akışa "error" parçası olarak düşer
|
// Model/sağlayıcı hatası akışa "error" parçası olarak düşer
|
||||||
let akisHatasi: string | null = null;
|
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 {
|
try {
|
||||||
const result = streamText({
|
const result = streamText({
|
||||||
model: sohbetDilModeli(),
|
model: sohbetDilModeli(),
|
||||||
@@ -53,7 +58,7 @@ export function danismanAkisi(opts: {
|
|||||||
prepareStep: ({ stepNumber }) =>
|
prepareStep: ({ stepNumber }) =>
|
||||||
stepNumber >= ARAC_TUR_SINIRI - 1 ? { toolChoice: "none" } : undefined,
|
stepNumber >= ARAC_TUR_SINIRI - 1 ? { toolChoice: "none" } : undefined,
|
||||||
maxOutputTokens: 1024,
|
maxOutputTokens: 1024,
|
||||||
abortSignal: AbortSignal.timeout(120_000),
|
abortSignal: zamanAsimi,
|
||||||
providerOptions: { openaiCompatible: { reasoningEffort: "none" } },
|
providerOptions: { openaiCompatible: { reasoningEffort: "none" } },
|
||||||
onError: ({ error }) => {
|
onError: ({ error }) => {
|
||||||
// Hata nesnesinin tamamı istek gövdesini ve cevap başlıklarını
|
// Hata nesnesinin tamamı istek gövdesini ve cevap başlıklarını
|
||||||
@@ -71,6 +76,8 @@ export function danismanAkisi(opts: {
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
const { done, value: parca } = await okuyucu.read();
|
const { done, value: parca } = await okuyucu.read();
|
||||||
if (done) break;
|
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")) {
|
if (parca.type === "text-start" && metin && !metin.endsWith("\n")) {
|
||||||
// Araç turundan sonra yeni metin parçası: kayıtta yapışmasın
|
// Araç turundan sonra yeni metin parçası: kayıtta yapışmasın
|
||||||
metin += "\n\n";
|
metin += "\n\n";
|
||||||
@@ -82,6 +89,8 @@ export function danismanAkisi(opts: {
|
|||||||
writer.write(parca);
|
writer.write(parca);
|
||||||
}
|
}
|
||||||
if (akisHatasi != null) throw new Error(akisHatasi);
|
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");
|
if (!metin.trim()) throw new Error("Boş cevap");
|
||||||
|
|
||||||
// Çıktı denetimi (jev.ts): cevap garanti/olasılık dili içeriyorsa
|
// Çıktı denetimi (jev.ts): cevap garanti/olasılık dili içeriyorsa
|
||||||
|
|||||||
Reference in New Issue
Block a user