fix(sync): memory/vector rebuilds are best-effort, not sync result; fix has_deep_reading_content import in asset_index.py

This commit is contained in:
Research Assistant 2026-05-18 22:09:42 +08:00
parent febaacbcd4
commit fad6eff83e
3 changed files with 44 additions and 32 deletions

View file

@ -64,17 +64,46 @@ def run(args: argparse.Namespace) -> int:
result = svc.run(verbose=verbose, json_output=json_output, selection_only=selection_only, index_only=index_only,
prune=prune_flag, prune_force=prune_force)
# Auto-build memory DB after successful sync so search works immediately
if result.ok and not dry_run:
try:
from paperforge.memory.builder import build_from_index
counts = build_from_index(vault)
logger.info("Memory DB built: %s papers indexed", counts.get("papers_indexed", 0))
except Exception as e:
logger.warning("Memory DB build skipped: %s", e)
if json_output:
print(result.to_json())
if result.ok and not dry_run:
try:
from paperforge.memory.builder import build_from_index
build_from_index(vault)
except Exception:
pass
try:
import subprocess, sys
subprocess.Popen(
[sys.executable, "-m", "paperforge", "embed", "build", "--resume"],
cwd=str(vault),
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == "win32" else 0,
)
except Exception:
pass
return 0
return 0 if result.ok else 1
if not result.ok:
return 1
# best-effort: rebuild memory DB for immediate search
try:
from paperforge.memory.builder import build_from_index
counts = build_from_index(vault)
print(f"memory: {counts.get('papers_indexed', 0)} papers indexed")
except Exception as e:
print(f"memory: deferred ({e})")
# best-effort: trigger vector resume in background
try:
import subprocess, sys
subprocess.Popen(
[sys.executable, "-m", "paperforge", "embed", "build", "--resume"],
cwd=str(vault),
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == "win32" else 0,
)
print("vector: resume started in background")
except Exception as e:
print(f"vector: deferred ({e})")
return 0

View file

@ -248,7 +248,6 @@ class SyncService:
index_count = 0
orphaned = 0
flat_cleaned = 0
memory_rebuild_error: Exception | None = None
if not selection_only:
from paperforge.worker._domain import load_domain_config
@ -283,15 +282,14 @@ class SyncService:
if orphaned > 0 or flat_cleaned > 0:
index_count = asset_index.build_index(self.vault, verbose)
# ├─ best-effort: rebuild memory DB (does not affect sync result)
try:
from paperforge.memory.builder import build_from_index
from paperforge.memory.db import get_memory_db_path
if get_memory_db_path(self.vault).exists():
build_from_index(self.vault)
except Exception as exc:
memory_rebuild_error = exc
logger.error("Failed to rebuild memory DB after sync: %s", exc)
logger.warning("memory rebuild deferred: %s", exc)
# ── Phase 4: Prune orphans ──
prune_result = None
@ -319,10 +317,7 @@ class SyncService:
total = sum(1 for _ in paths["literature"].rglob("*.md")) if paths["literature"].exists() else 0
print(f"index-refresh: {total} formal note(s) in literature")
all_errors = list(selection_result.get("errors", []))
if memory_rebuild_error is not None:
all_errors.append(f"memory rebuild failed: {memory_rebuild_error}")
is_ok = selection_result.get("failed", 0) == 0 and len(all_errors) == 0
is_ok = selection_result.get("failed", 0) == 0 and not selection_result.get("errors")
result = PFResult(
ok=is_ok,
@ -338,18 +333,6 @@ class SyncService:
if _export_code != "ok":
result.warnings.append(f"BBT exports: {_export_code}")
if memory_rebuild_error is not None:
result.error = PFError(
code=ErrorCode.SYNC_FAILED,
message=f"Sync completed but memory rebuild failed: {memory_rebuild_error}",
details={"phase": "memory_rebuild", "exception_type": type(memory_rebuild_error).__name__},
suggestions=["Run paperforge memory build to rebuild the memory DB from the cleaned canonical index."],
)
result.next_actions.append({
"command": "paperforge memory build",
"reason": "Rebuild memory DB so it matches the cleaned canonical index",
})
return result
def prune(self, paths: dict, fresh_index: dict | None = None, *, dry_run: bool = True) -> dict:

View file

@ -277,10 +277,10 @@ def _build_entry(item: dict, vault: Path, paths: dict, domain: str, zotero_dir:
)
from paperforge.worker.ocr import validate_ocr_meta
from paperforge.worker.paper_meta import write_paper_meta
from paperforge.adapters.obsidian_frontmatter import has_deep_reading_content
from paperforge.worker.sync import (
collection_fields,
frontmatter_note,
has_deep_reading_content,
obsidian_wikilink_for_path,
obsidian_wikilink_for_pdf,
)
@ -488,8 +488,8 @@ def _vec_auto_embed_if_new(vault: Path, entry: dict) -> None:
return
# Check if vector DB is enabled and set up
try:
from paperforge.embedding._config import _read_plugin_settings
from paperforge.embedding import embed_paper, get_vector_db_path
from paperforge.embedding._config import _read_plugin_settings
from paperforge.memory.chunker import chunk_fulltext
settings = _read_plugin_settings(vault)
if not settings.get("features", {}).get("vector_db", False):