Files

25 lines
2.2 KiB
PHP

<?php
/** ingest_v2nav_kb.php — Re-ingest della guida UI V2 CORRETTA (sostituisce i chunk stale del 12/6). Idempotente. */
if (PHP_SAPI !== 'cli') { http_response_code(403); exit("CLI only\n"); }
require_once dirname(__DIR__).'/config/env.php';
require_once dirname(__DIR__).'/config/config.php';
require_once dirname(__DIR__).'/config/database.php';
require_once dirname(__DIR__).'/services/EmbedService.php';
require_once dirname(__DIR__).'/services/VectorService.php';
function logln($m){ echo '['.date('H:i:s')."] $m\n"; }
function uuid(){ $b=random_bytes(16); $b[6]=chr((ord($b[6])&0x0f)|0x40); $b[8]=chr((ord($b[8])&0x3f)|0x80); return vsprintf('%s%s-%s-%s-%s-%s%s%s',str_split(bin2hex($b),4)); }
function chunkText($t,$size=2000,$ov=200){ $c=[];$len=mb_strlen($t,'UTF-8');$s=0; while($s<$len){$take=min($size,$len-$s);$p=mb_substr($t,$s,$take,'UTF-8');if(trim($p)!=='')$c[]=$p;if($s+$take>=$len)break;$s+=($size-$ov);} return $c; }
$SOURCE='NIS2 Agile — Guida interfaccia V2 (Bootstrap Italia)';
$TITLE ='Interfaccia V2 NIS2 Agile — navigazione e moduli';
$f=__DIR__.'/_v2nav.md'; if(!is_file($f)){ exit("doc mancante\n"); }
$text=preg_replace('/\n{3,}/',"\n\n",trim((string)file_get_contents($f)));
$chunks=chunkText($text);
logln("testo ".strlen($text)." char -> ".count($chunks)." chunk");
$embed=new EmbedService(); $vector=new VectorService(); $vector->ensureCollection($embed->dims);
try{ $vector->deleteByFilter(['must'=>[['key'=>'scope','match'=>['value'=>'SYSTEM']],['key'=>'source','match'=>['value'=>$SOURCE]]]]); logln("rimossi chunk stale per source"); }catch(Throwable $e){ logln("warn delete: ".$e->getMessage()); }
$du=uuid(); $pts=[];
foreach($chunks as $i=>$ck){ $v=null; for($t=1;$t<=5;$t++){ try{$v=$embed->embed($ck);break;}catch(Throwable $e){ if($t==5)throw $e; sleep($t);} }
$pts[]=['id'=>uuid(),'vector'=>$v,'payload'=>['doc_uuid'=>$du,'title'=>$TITLE.($i>0?' (parte '.($i+1).')':''),'chunk'=>$ck,'entity_type'=>'guida_prodotto','source'=>$SOURCE,'lang'=>'it','scope'=>'SYSTEM','consulting_firm_id'=>null,'organization_id'=>null,'shared_with_orgs'=>[],'uploaded_by'=>0]]; }
foreach(array_chunk($pts,64) as $b) $vector->upsertBatch($b);
logln("upsert OK: ".count($pts)." chunk SYSTEM");