40 lines
2.7 KiB
JavaScript
40 lines
2.7 KiB
JavaScript
import { createHash } from 'node:crypto';
|
||
import { splitAnalysisText } from './analysis-parts.mjs';
|
||
import { qualifyOfferDraft } from './offer-draft.mjs';
|
||
|
||
/** Draft-specific merging: the general specification schema cannot merge sections. */
|
||
export async function draftOfferInParts(context, requested, runPart, {signal} = {}) {
|
||
const parts = splitAnalysisText(context, 16000), results = new Map();
|
||
for (let start = 0; start < parts.length; start += 2) {
|
||
signal?.throwIfAborted();
|
||
await Promise.all(parts.slice(start, start + 2).map(async part => {
|
||
try {
|
||
const result = qualifyOfferDraft(await runPart(part, parts.length), requested);
|
||
results.set(part.index, result);
|
||
} catch (error) {
|
||
signal?.throwIfAborted();
|
||
results.set(part.index, null);
|
||
}
|
||
}));
|
||
}
|
||
signal?.throwIfAborted();
|
||
if (![...results.values()].some(Boolean)) throw new Error('Taslak için hiçbir kaynak bölümü işlenemedi. Yeniden deneyin.');
|
||
if (parts.length === 1) return results.get(0);
|
||
const failedParts = parts.filter(part => !results.get(part.index)).map(part => part.index + 1);
|
||
const missingSections = requested.filter(title => parts.some(part => !results.get(part.index) || results.get(part.index).draftReview.missingSections.includes(title)));
|
||
const bolumler = requested.map(baslik => ({baslik, icerik:parts.map(part => {
|
||
const found = results.get(part.index)?.bolumler.find(row => row.baslik === baslik);
|
||
return `Kaynak bölümü ${part.index + 1}/${parts.length}:\n${found?.icerik || '[DOLDURUN: Bu kaynak bölümünün taslağı üretilemedi; kaynak metni kontrol edin.]'}`;
|
||
}).join('\n\n')}));
|
||
// Unexpected but useful sections remain visible and attributed to their input part.
|
||
for (const part of parts) for (const row of results.get(part.index)?.bolumler || []) {
|
||
if (!requested.includes(row.baslik)) bolumler.push({...row, baslik:`${row.baslik} (Kaynak bölümü ${part.index + 1})`});
|
||
}
|
||
return {bolumler, draftReview:{status:'partial', requestedSections:requested, missingSections,
|
||
extraSections:bolumler.slice(requested.length).map(row => row.baslik), failedParts,
|
||
sourceHash:createHash('sha256').update(context).digest('hex'),
|
||
parts:parts.map(part => ({index:part.index + 1,start:part.start,end:part.end,status:results.get(part.index) ? 'processed' : 'failed'})),
|
||
note:`Uzun kaynak ${parts.length} bölümde işlendi. ${failedParts.length ? `${failedParts.length} bölüm üretilemedi. ` : ''}Bölüm taslakları kaynak sırasıyla birleştirildi; tekrarlar ve bölümler arası çelişkiler kullanıcı tarafından kontrol edilmelidir. Her kaynak parçasının işlenmesi, içindeki her şartın doğru karşılandığını kanıtlamaz. Bu çıktı resmi başvuruya hazır değildir.`,
|
||
}};
|
||
}
|