Spaces:
Running on Zero
Running on Zero
| #!/usr/bin/env python3 | |
| """One-off migration: repair PDF font-map damage in the existing RAG index. | |
| The chunks were extracted before `controlai_rag.textfix` existed, so the damage | |
| is baked into `data/rag_index/chunks.json`. The corruption is deterministic, so | |
| the chunks can be repaired in place -- no re-extraction of the source PDFs, and | |
| chunk ids stay stable, which keeps the dense index aligned. | |
| Rebuilds BM25 here; run `python -m controlai_rag.retriever --build` afterwards | |
| to regenerate the embeddings from the repaired text. | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import pickle | |
| import shutil | |
| import sys | |
| from pathlib import Path | |
| PROJECT_ROOT = Path(__file__).resolve().parents[1] | |
| if str(PROJECT_ROOT) not in sys.path: | |
| sys.path.insert(0, str(PROJECT_ROOT)) | |
| from controlai_rag.index import INDEX_DIR, tokenize_corpus | |
| from controlai_rag.textfix import looks_damaged, repair | |
| def main() -> int: | |
| chunks_path = INDEX_DIR / "chunks.json" | |
| chunks = json.loads(chunks_path.read_text(encoding="utf-8")) | |
| backup = chunks_path.with_suffix(".json.pre-textfix") | |
| if not backup.exists(): | |
| shutil.copy2(chunks_path, backup) | |
| print(f"Backed up original to {backup.name}") | |
| damaged = repaired = 0 | |
| for chunk in chunks: | |
| text = chunk.get("text", "") | |
| if not looks_damaged(text): | |
| continue | |
| damaged += 1 | |
| fixed = repair(text) | |
| if fixed != text: | |
| chunk["text"] = fixed | |
| repaired += 1 | |
| print(f"{damaged} damaged chunks found, {repaired} repaired, {len(chunks)} total") | |
| chunks_path.write_text(json.dumps(chunks, ensure_ascii=False, indent=2), encoding="utf-8") | |
| from rank_bm25 import BM25Okapi | |
| print("Rebuilding BM25 over the repaired text ...") | |
| bm25 = BM25Okapi([tokenize_corpus(c["text"]) for c in chunks]) | |
| (INDEX_DIR / "bm25.pkl").write_bytes(pickle.dumps(bm25)) | |
| print("Done. Now run: python -m controlai_rag.retriever --build") | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |