Preserve full draft sections and disclose missing requested content

This commit is contained in:
2026-09-06 10:11:44 +03:00
parent a78aaef7e5
commit 996cc15245
5 changed files with 76 additions and 7 deletions
+3 -6
View File
@@ -1,3 +1,4 @@
import { qualifyOfferDraft } from './offer-draft.mjs';
import { createHash } from 'node:crypto';
import { questionChunks, qualifyQuestionAnswer } from './document-question.mjs';
import { qualifyOfferAudit } from './offer-audit.mjs';
@@ -117,11 +118,7 @@ export async function teklifTaslak({ ikn, tur, tender, firma, belgeler, fiyat, g
Array.isArray(belgeler) && belgeler.length ? 'DEPODAKİ BELGELER:\n' + belgeler.slice(0, 40).map((b) => `- ${b.ad || b}${b.kategori ? ' [' + b.kategori + ']' : ''}`).join('\n') : null,
fiyat ? `FİYAT VERİSİ: ${typeof fiyat === 'string' ? fiyat : JSON.stringify(fiyat).slice(0, 1500)}` : null,
].filter(Boolean).join('\n\n');
const sistem = `Sen Türkiye kamu ihalelerinde (4734) deneyimli bir teklif yazarısın. Verilen bilgilerle resmî, kısa ve somut bir teklif dosyası taslağı yaz. Verilmeyen bilgiyi UYDURMA: firma adı, yetkili, tarih, fiyat, süre boşluklarına [DOLDURUN: ...] yaz. Fiyat yalnızca FİYAT VERİSİ varsa yazılır. Ekler bölümünde istenen belgeleri madde madde ver. Üslup resmî; abartı yok. Yalnızca JSON: {"bolumler":[{"baslik":"","icerik":""}]} — istenen bölümleri aynı sırada ver.`;
const sistem = `Sen Türkiye kamu ihalelerinde (4734) deneyimli bir teklif yazarısın. Verilen bilgilerle resmî, kısa ve somut bir teklif dosyası taslağı yaz. Verilmeyen bilgiyi UYDURMA: firma adı, yetkili, tarih, fiyat, süre boşluklarına [DOLDURUN: ...] yaz. Fiyat yalnızca FİYAT VERİSİ varsa yazılır. Ekler bölümünde istenen belgeleri madde madde ver. Üslup resmî; abartı yok. Yalnızca JSON: {"bolumler":[{"baslik":"","icerik":""}]} — istenen bölümleri aynı sırada ver; bölüm başlıklarını değiştirmeden aynen kopyala.`;
const out = await analyzeSpec({ text: `BAĞLAM:\n${baglam}\n\nİSTENEN BÖLÜMLER:\n${istenen.map((x, i) => `${i + 1}. ${x}`).join('\n')}\n\nYalnızca JSON döndür.`, tender, chain, systemOverride: sistem, mode: 'derin' });
const bolumler = (Array.isArray(out?.result?.bolumler) ? out.result.bolumler : [])
.map((b) => ({ baslik: String(b?.baslik ?? '').slice(0, 200), icerik: String(b?.icerik ?? '').slice(0, 12000) }))
.filter((b) => b.baslik && b.icerik);
if (!bolumler.length) throw new Error('Model bölüm üretmedi; tekrar deneyin.');
return { bolumler };
return qualifyOfferDraft(out?.result, istenen);
}
+30
View File
@@ -0,0 +1,30 @@
const normalize = value => value.normalize('NFC').replace(/\s+/g, ' ').trim();
/** Preserve useful draft text, while making missing requested sections explicit. */
export function qualifyOfferDraft(result, requested) {
if (!Array.isArray(result?.bolumler) || !result.bolumler.length)
throw new Error('Model bölüm üretmedi; tekrar deneyin.');
const byTitle = new Map();
for (const row of result.bolumler) {
if (typeof row?.baslik !== 'string' || typeof row?.icerik !== 'string' || !row.baslik.trim())
throw new Error('Model geçersiz bir taslak bölümü döndürdü. Yeniden deneyin.');
const key = normalize(row.baslik);
if (byTitle.has(key)) throw new Error('Model aynı taslak bölümünü birden fazla kez döndürdü. Yeniden deneyin.');
byTitle.set(key, {baslik:row.baslik.trim(), icerik:row.icerik.trim()});
}
const missingSections = [];
const bolumler = requested.map(baslik => {
const key = normalize(baslik), found = byTitle.get(key);
byTitle.delete(key);
if (found?.icerik) return {...found, baslik};
missingSections.push(baslik);
return {baslik, icerik:`[DOLDURUN: ${baslik} bölümü model tarafından tamamlanmadı. Kaynak belgelerle hazırlayın.]`};
});
// Keep unexpected useful content; it cannot substitute for a missing section.
const extraSections = [...byTitle.values()].filter(row => row.icerik);
return {bolumler:[...bolumler, ...extraSections], draftReview:{
status:missingSections.length || extraSections.length ? 'partial' : 'draft',
requestedSections:requested, missingSections, extraSections:extraSections.map(row=>row.baslik),
note:'Bu çıktı düzenlenebilir bir taslaktır. Bölümlerin bulunması, bilgilerin doğru veya resmi teklif dosyasının hazır olduğunu göstermez. Kaynak, firma bilgileri, fiyatlar ve zorunlu belgeler ayrıca kontrol edilmelidir.',
}};
}