github-actions[bot]
Auto-sync backend from GitHub
866e276
Raw
History Blame Contribute Delete
2.48 kB
from __future__ import annotations
import json
from pathlib import Path
from threading import Lock
from typing import Any
BASE_DIR = Path(__file__).resolve().parent
SEED_FILE = BASE_DIR / "seed_data.json"
_LOCK = Lock()
def _ensure_seed_file() -> None:
if not SEED_FILE.exists():
SEED_FILE.write_text("[]
", encoding="utf-8")
def load_entries() -> list[dict[str, Any]]:
_ensure_seed_file()
with SEED_FILE.open("r", encoding="utf-8") as handle:
data = json.load(handle)
if not isinstance(data, list):
raise ValueError("Knowledge base seed_data.json must contain a list")
return [entry for entry in data if isinstance(entry, dict)]
def _save_entries(entries: list[dict[str, Any]]) -> None:
tmp = SEED_FILE.with_suffix(".json.tmp")
with tmp.open("w", encoding="utf-8") as handle:
json.dump(entries, handle, indent=2, ensure_ascii=False)
handle.write("
")
tmp.replace(SEED_FILE)
def next_entry_id(entries: list[dict[str, Any]]) -> str:
max_num = 0
for entry in entries:
entry_id = str(entry.get("id", ""))
if entry_id.startswith("kb_"):
suffix = entry_id[3:]
if suffix.isdigit():
max_num = max(max_num, int(suffix))
return f"kb_{max_num + 1:03d}"
def normalize_entry(entry: dict[str, Any]) -> dict[str, Any]:
required = ["topic", "title", "content", "source", "tags"]
missing = [key for key in required if not entry.get(key)]
if missing:
raise ValueError(f"Missing required knowledge base fields: {', '.join(missing)}")
tags = entry.get("tags")
if not isinstance(tags, list):
raise ValueError("tags must be a list of strings")
return {
"id": str(entry.get("id") or "").strip(),
"topic": str(entry["topic"]).strip(),
"title": str(entry["title"]).strip(),
"content": str(entry["content"]).strip(),
"source": str(entry["source"]).strip(),
"tags": [str(tag).strip() for tag in tags if str(tag).strip()],
}
def append_entry(entry: dict[str, Any]) -> dict[str, Any]:
with _LOCK:
entries = load_entries()
normalized = normalize_entry(entry)
if not normalized["id"]:
normalized["id"] = next_entry_id(entries)
entries.append(normalized)
_save_entries(entries)
return normalized
def update_entries(entries: list[dict[str, Any]]) -> None:
with _LOCK:
_save_entries(entries)