Initial SQL-only 1C adapter baseline
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from common import read_json
|
||||
from prepare_1c_rag_corpus import SUPPORTED_EXTENSIONS, classify_source, normalize_text, parse_front_matter
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
DEFAULT_SOURCE_DIR = ROOT / "plugins" / "1c" / "rag" / "sources"
|
||||
DEFAULT_MANIFEST = ROOT / "plugins" / "1c" / "datasets" / "prepared" / "rag_manifest.json"
|
||||
|
||||
|
||||
def iter_source_files(source_dir: Path) -> list[Path]:
|
||||
if not source_dir.exists():
|
||||
return []
|
||||
return sorted(
|
||||
path
|
||||
for path in source_dir.rglob("*")
|
||||
if path.is_file() and path.suffix.lower() in SUPPORTED_EXTENSIONS
|
||||
)
|
||||
|
||||
|
||||
def source_state(source_dir: Path) -> dict[str, dict]:
|
||||
state = {}
|
||||
for path in iter_source_files(source_dir):
|
||||
relative_path = path.relative_to(source_dir).as_posix()
|
||||
text = normalize_text(path.read_text(encoding="utf-8"))
|
||||
front_matter, body = parse_front_matter(text)
|
||||
chunk_source_text = body or text
|
||||
state[relative_path] = {
|
||||
"source_path": relative_path,
|
||||
"source_type": classify_source(path, chunk_source_text, front_matter),
|
||||
"file_type": path.suffix.lower().lstrip("."),
|
||||
"content_hash": hashlib.sha256(text.encode("utf-8")).hexdigest(),
|
||||
}
|
||||
return state
|
||||
|
||||
|
||||
def compare_manifest(source_dir: Path, manifest_path: Path) -> dict:
|
||||
current = source_state(source_dir)
|
||||
if not manifest_path.exists():
|
||||
return {
|
||||
"status": "stale" if current else "missing",
|
||||
"reason": "manifest is missing",
|
||||
"new": sorted(current),
|
||||
"changed": [],
|
||||
"deleted": [],
|
||||
"type_changed": [],
|
||||
}
|
||||
|
||||
manifest = read_json(manifest_path)
|
||||
recorded = {
|
||||
str(source.get("source_path")): source
|
||||
for source in manifest.get("sources") or []
|
||||
if isinstance(source, dict) and source.get("source_path")
|
||||
}
|
||||
|
||||
current_paths = set(current)
|
||||
recorded_paths = set(recorded)
|
||||
new = sorted(current_paths - recorded_paths)
|
||||
deleted = sorted(recorded_paths - current_paths)
|
||||
changed = []
|
||||
type_changed = []
|
||||
|
||||
for source_path in sorted(current_paths & recorded_paths):
|
||||
current_source = current[source_path]
|
||||
recorded_source = recorded[source_path]
|
||||
if current_source["content_hash"] != recorded_source.get("content_hash"):
|
||||
changed.append(source_path)
|
||||
if current_source["source_type"] != recorded_source.get("source_type"):
|
||||
type_changed.append(
|
||||
{
|
||||
"source_path": source_path,
|
||||
"current": current_source["source_type"],
|
||||
"manifest": recorded_source.get("source_type"),
|
||||
}
|
||||
)
|
||||
|
||||
stale = bool(new or deleted or changed or type_changed)
|
||||
return {
|
||||
"status": "stale" if stale else "fresh",
|
||||
"source_dir": str(source_dir),
|
||||
"manifest": str(manifest_path),
|
||||
"source_count": len(current),
|
||||
"manifest_source_count": len(recorded),
|
||||
"new": new,
|
||||
"changed": changed,
|
||||
"deleted": deleted,
|
||||
"type_changed": type_changed,
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="Check whether the 1C RAG manifest is fresh.")
|
||||
parser.add_argument("--source-dir", type=Path, default=DEFAULT_SOURCE_DIR)
|
||||
parser.add_argument("--manifest", type=Path, default=DEFAULT_MANIFEST)
|
||||
parser.add_argument("--print", action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
report = compare_manifest(args.source_dir, args.manifest)
|
||||
if args.print:
|
||||
print(json.dumps(report, ensure_ascii=False, indent=2))
|
||||
else:
|
||||
print(f"1C RAG freshness: {report['status']}")
|
||||
return 0 if report["status"] in {"fresh", "missing"} else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user