Cancel disconnected offer analysis and stop remaining provider calls

This commit is contained in:
2026-09-06 10:22:29 +03:00
parent 673d6c1bc8
commit d534ea20b9
10 changed files with 110 additions and 22 deletions
+10 -4
View File
@@ -317,11 +317,12 @@ function kesikJsonOnar(s) {
}
/** Zinciri sırayla dener; ilk başarılı sonucu döndürür. */
export async function analyzeSpec({ text, fileName, tender, chain, systemOverride, mode, extraction, _singlePart = false }) {
export async function analyzeSpec({ text, fileName, tender, chain, systemOverride, mode, extraction, signal, _singlePart = false }) {
signal?.throwIfAborted();
if (!_singlePart && String(text || '').length > 24000) {
return analyzeInParts({text,fileName,tender,mode,extraction}, part => analyzeSpec({
return analyzeInParts({text,fileName,tender,mode,extraction,signal}, part => analyzeSpec({
text:part.text,fileName:`${fileName || 'Doküman'} — bölüm ${part.index+1}`,
tender:tender ? {...tender,items:[]} : undefined,chain,mode,_singlePart:true,
tender:tender ? {...tender,items:[]} : undefined,chain,mode,signal,_singlePart:true,
systemOverride:(systemOverride || (mode === 'derin' ? DERIN_SYSTEM_PROMPT : SYSTEM_PROMPT)) + '\nBu metin büyük dokümanın bir bölümüdür. Yalnız bu bölümde görülen koşulları çıkar; bu bölümde bulunmayan şartın bütün dokümanda bulunmadığı sonucunu çıkarma.',
}));
}
@@ -342,6 +343,7 @@ export async function analyzeSpec({ text, fileName, tender, chain, systemOverrid
const attempts = [];
for (const id of order) {
signal?.throwIfAborted();
const p = PROVIDERS[id];
const route = routeFor(id);
if (!route) {
@@ -349,6 +351,8 @@ export async function analyzeSpec({ text, fileName, tender, chain, systemOverrid
continue;
}
const ac = new AbortController();
const cancel = () => ac.abort();
signal?.addEventListener('abort',cancel,{once:true});
const timer = setTimeout(() => ac.abort(), timeoutMs);
try {
let raw;
@@ -361,6 +365,7 @@ export async function analyzeSpec({ text, fileName, tender, chain, systemOverrid
} else {
raw = await callOpenAiStyle(p, route.key, route.model, userPrompt, ac.signal, sistem, maxTokens);
}
signal?.throwIfAborted();
const parsed = extractJson(raw);
const result = qualifyAnalysis(parsed,{text,fileName,extraction,limit:derin ? 90000 : 60000,
expectedItems:tender?.items?.length || 0,repaired:parsed._outputRepaired === true});
@@ -372,9 +377,10 @@ export async function analyzeSpec({ text, fileName, tender, chain, systemOverrid
attempts,
};
} catch (e) {
signal?.throwIfAborted();
attempts.push({ id, ok: false, yol: route.yol, error: e.name === 'AbortError' ? 'zaman aşımı' : e.message });
} finally {
clearTimeout(timer);
clearTimeout(timer);signal?.removeEventListener('abort',cancel);
}
}
const err = new Error('Tüm AI sağlayıcıları başarısız oldu: ' + attempts.map((a) => `${a.id}(${a.error})`).join(', '));