Implement KB sync after Notion page updates with block ID verification

- Add NotionKBSyncService for immediate KB updates after page changes
- Implement block ID verification to ensure content freshness
- Refactor duplicate block processing logic to shared utils
- Add user-friendly status messages
- Include debug logging for troubleshooting
This commit is contained in:
CREDO23 2026-02-17 20:30:12 +02:00
parent 2f65536c6d
commit 7d1bd1fab4
5 changed files with 150 additions and 58 deletions

View file

@ -26,6 +26,7 @@ class NotionKBSyncService:
appended_content: str,
user_id: str,
search_space_id: int,
appended_block_ids: list[str] | None = None,
) -> dict:
from app.tasks.connector_indexers.base import (
get_current_timestamp,
@ -33,13 +34,70 @@ class NotionKBSyncService:
)
try:
logger.debug(f"Starting KB sync for document {document_id}")
document = await self.db_session.get(Document, document_id)
if not document:
logger.warning(f"Document {document_id} not found in KB")
return {"status": "not_indexed"}
new_content = document.content + "\n\n" + appended_content
page_id = document.document_metadata.get("page_id")
if not page_id:
logger.error(f"Document {document_id} missing page_id in metadata")
return {"status": "error", "message": "Missing page_id in metadata"}
logger.debug(
f"Document found: id={document_id}, page_id={page_id}, connector_id={document.connector_id}"
)
from app.connectors.notion_history import NotionHistoryConnector
notion_connector = NotionHistoryConnector(
session=self.db_session, connector_id=document.connector_id
)
logger.debug(f"Fetching page content from Notion for page {page_id}")
blocks, _ = await notion_connector.get_page_content(page_id, page_title=None)
from app.utils.notion_utils import extract_all_block_ids, process_blocks
fetched_content = process_blocks(blocks)
logger.debug(f"Fetched content length: {len(fetched_content)} chars")
content_verified = False
if appended_block_ids:
fetched_block_ids = set(extract_all_block_ids(blocks))
found_blocks = [
bid for bid in appended_block_ids if bid in fetched_block_ids
]
logger.debug(
f"Block verification: {len(found_blocks)}/{len(appended_block_ids)} blocks found"
)
logger.debug(
f"Appended IDs (first 3): {appended_block_ids[:3]}, Fetched IDs count: {len(fetched_block_ids)}"
)
if len(found_blocks) >= 1:
logger.info(
f"Content verified fresh: found {len(found_blocks)} appended blocks"
)
full_content = fetched_content
content_verified = True
else:
logger.warning(
"No appended blocks found in fetched content - appending manually"
)
full_content = fetched_content + "\n\n" + appended_content
content_verified = False
else:
logger.warning("No block IDs provided - using fetched content as-is")
full_content = fetched_content
content_verified = False
logger.debug(f"Final content length: {len(full_content)} chars, verified={content_verified}")
logger.debug("Generating summary and embeddings")
user_llm = await get_user_long_context_llm(
self.db_session, user_id, search_space_id
)
@ -52,22 +110,28 @@ class NotionKBSyncService:
"connector_type": "Notion",
}
summary_content, summary_embedding = await generate_document_summary(
new_content, user_llm, document_metadata_for_summary
full_content, user_llm, document_metadata_for_summary
)
logger.debug(f"Generated summary length: {len(summary_content)} chars")
else:
summary_content = f"Notion Page: {document.document_metadata.get('page_title')}\n\n{new_content[:500]}..."
logger.warning("No LLM configured - using fallback summary")
summary_content = f"Notion Page: {document.document_metadata.get('page_title')}\n\n{full_content[:500]}..."
summary_embedding = config.embedding_model_instance.embed(
summary_content
)
logger.debug(f"Deleting old chunks for document {document_id}")
await self.db_session.execute(
delete(Chunk).where(Chunk.document_id == document.id)
)
chunks = await create_document_chunks(new_content)
logger.debug("Creating new chunks")
chunks = await create_document_chunks(full_content)
logger.debug(f"Created {len(chunks)} chunks")
logger.debug("Updating document fields")
document.content = summary_content
document.content_hash = generate_content_hash(new_content)
document.content_hash = generate_content_hash(full_content, search_space_id)
document.embedding = summary_embedding
document.document_metadata = {
**document.document_metadata,
@ -76,9 +140,14 @@ class NotionKBSyncService:
safe_set_chunks(document, chunks)
document.updated_at = get_current_timestamp()
logger.debug("Committing changes to database")
await self.db_session.commit()
logger.info(f"Successfully synced KB for document {document_id}")
logger.info(
f"Successfully synced KB for document {document_id}: "
f"summary={len(summary_content)} chars, chunks={len(chunks)}, "
f"content_verified={content_verified}"
)
return {"status": "success"}
except Exception as e: