import {qualifyAnalysis} from './analysis-quality.mjs'; import {analysisArrayFields,validateAnalysisShape} from './analysis-schema.mjs'; export function splitAnalysisText(text,max=24000) { if(!Number.isInteger(max) || max<100)throw new Error('Geçersiz parça boyutu.'); const source=String(text || ''),parts=[]; for(let start=0;startstart+max/2)end=newline+1;} // Do not split a UTF-16 surrogate pair. if(end{ try { const out=await runPart(part); validateAnalysisShape(out?.result); results.push({part,out}); } catch(error){failures.push({part,error:String(error.message || error)});} })); } results.sort((a,b)=>a.part.index-b.part.index); if(!results.length)throw new Error('Dokümanın hiçbir parçası analiz edilemedi.'); const merged={},issues=failures.map(f=>`${f.part.index+1}. parça analiz edilemedi.`); const pathMap=new Map(); for(const field of arrayFields) { merged[field]=[]; const entries=new Map(); for(const {part,out} of results) for(const [i,value] of (out.result[field] || []).entries()) { const key=JSON.stringify(value); let index=field==='itemsAndSpecs'?undefined:entries.get(key); if(index===undefined) { index=merged[field].length;entries.set(key,index); merged[field].push(field==='itemsAndSpecs'?{...value,sourcePart:part.index+1,sourceRange:{start:part.start,end:part.end}}:value); } pathMap.set(`${part.index}:${field}.${i}`,`${field}.${index}`); } } merged.citations=results.flatMap(({part,out})=>(out.result.citations || []).flatMap(c=>{ const path=pathMap.get(`${part.index}:${c.path}`);return path?[{path,quote:c.quote}]:[]; })); for(const field of ['summary','scopeOfWork'])merged[field]=results.map(({part,out})=>out.result[field] ? `Bölüm ${part.index+1}: ${out.result[field]}` : '').filter(Boolean).join('\n\n'); // Different part-level prices/strategies cannot be treated as a global bid. merged.bidAnalysis=null; const quantities=new Map(); for(const row of merged.itemsAndSpecs) { const key=JSON.stringify([row.itemNumber ?? row.no ?? null,row.kisim ?? null,row.name]); if(quantities.has(key) && quantities.get(key)!==row.quantity)issues.push(`${row.name}: bölümler arasında farklı miktar/birim bulundu.`); quantities.set(key,row.quantity); } for(const {part,out} of results) for(const issue of out.result.sourceReview?.issues || [])issues.push(`Bölüm ${part.index+1}: ${issue}`); const result=qualifyAnalysis(merged,{text:input.text,limit:String(input.text).length,fileName:input.fileName,expectedItems:input.tender?.items?.length || 0}); const ownIssues=[...result.sourceReview.issues,...issues]; result.sourceReview={...result.sourceReview,status:ownIssues.length?'partial':'review_required',issues:ownIssues, analyzedCharacters:results.reduce((sum,{part})=>sum+part.end-part.start,0), parts:parts.map(part=>({index:part.index+1,start:part.start,end:part.end,status:failures.some(f=>f.part.index===part.index)?'failed':'processed'}))}; return {result,mode:input.mode==='derin'?'derin':'standart',model:{id:'document-parts',label:'Doküman analizi',provider:'',model:'document-parts'}, attempts:results.flatMap(({part,out})=>(out.attempts || []).map(a=>({...a,part:part.index+1}))), partFailures:failures.map(({part})=>({part:part.index+1}))}; }