Spaces:
Runtime error
Runtime error
| """Re-index user-edited section text into the vector store for immediate hierarchical RAG.""" | |
| from __future__ import annotations | |
| import logging | |
| from langchain_core.documents import Document | |
| from app.config import settings | |
| from app.ingest.hierarchy import build_hierarchical_documents | |
| from app.ingest.pipeline import stamp_chunks_for_index | |
| from app.vectorstore.factory import get_vectorstore | |
| logger = logging.getLogger(__name__) | |
| def runtime_section_vector_doc_id(report_id: str, section_code: str) -> str: | |
| """Stable virtual ``doc_id`` for a report section overlay (document + section + paragraph tiers).""" | |
| return f"runtime-{report_id}-{section_code}" | |
| def upsert_runtime_section_index( | |
| *, | |
| tenant_id: str, | |
| virtual_doc_id: str, | |
| section_title: str, | |
| body_text: str, | |
| ) -> int: | |
| """Remove prior chunks for ``virtual_doc_id`` and insert fresh hierarchical rows. | |
| Returns: | |
| Number of chunks written (0 if ``body_text`` is empty after stripping). | |
| """ | |
| vs = get_vectorstore() | |
| vs.delete_document(virtual_doc_id) | |
| text = (body_text or "").strip() | |
| if not text: | |
| logger.info("runtime RAG: cleared index for doc=%s", virtual_doc_id) | |
| return 0 | |
| from app.services.document_sanitiser import sanitise_text_for_rag_sync | |
| text = sanitise_text_for_rag_sync(text, tenant_id=tenant_id) | |
| if not text: | |
| logger.info("runtime RAG: empty after sanitisation doc=%s", virtual_doc_id) | |
| return 0 | |
| label = (section_title or "").strip() or virtual_doc_id | |
| raw = [Document(page_content=text, metadata={"source": label})] | |
| hier = build_hierarchical_documents( | |
| raw, | |
| doc_id=virtual_doc_id, | |
| filename=label, | |
| chunk_size=settings.chunk_size, | |
| chunk_overlap=settings.chunk_overlap, | |
| ) | |
| stamped = stamp_chunks_for_index(hier, doc_id=virtual_doc_id, tenant_id=tenant_id) | |
| vs.add_documents(stamped) | |
| logger.info( | |
| "runtime RAG: indexed %d chunks for doc=%s tenant=%s", | |
| len(stamped), | |
| virtual_doc_id, | |
| tenant_id, | |
| ) | |
| return len(stamped) | |
| async def upsert_runtime_section_index_async( | |
| *, | |
| tenant_id: str, | |
| virtual_doc_id: str, | |
| section_title: str, | |
| body_text: str, | |
| ) -> int: | |
| """Non-blocking wrapper for :func:`upsert_runtime_section_index`.""" | |
| from app.async_executor import run_sync_in_executor | |
| return await run_sync_in_executor( | |
| lambda: upsert_runtime_section_index( | |
| tenant_id=tenant_id, | |
| virtual_doc_id=virtual_doc_id, | |
| section_title=section_title, | |
| body_text=body_text, | |
| ) | |
| ) | |