fix cluster-only label persistence, wiki data-loss guard, ollama error message (#744 #746 #750)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Safi
2026-05-06 11:56:04 +01:00
co-authored by Claude Sonnet 4.6
parent 48888a7c26
commit e22a189df1
4 changed files with 27 additions and 4 deletions
+17 -2
View File
@@ -1546,7 +1546,15 @@ def main() -> None:
cohesion = score_all(G, communities)
gods = god_nodes(G)
surprises = surprising_connections(G, communities)
labels = {cid: f"Community {cid}" for cid in communities}
out = watch_path / "graphify-out"
labels_path = out / ".graphify_labels.json"
if labels_path.exists():
try:
labels = {int(k): v for k, v in json.loads(labels_path.read_text(encoding="utf-8")).items()}
except Exception:
labels = {cid: f"Community {cid}" for cid in communities}
else:
labels = {cid: f"Community {cid}" for cid in communities}
questions = suggest_questions(G, communities, labels)
tokens = {"input": 0, "output": 0}
from graphify.export import _git_head as _gh
@@ -1555,9 +1563,9 @@ def main() -> None:
{"warning": "cluster-only mode — file stats not available"},
tokens, str(watch_path), suggested_questions=questions,
min_community_size=min_community_size, built_at_commit=_commit)
out = watch_path / "graphify-out"
(out / "GRAPH_REPORT.md").write_text(report, encoding="utf-8")
to_json(G, communities, str(out / "graph.json"))
labels_path.write_text(json.dumps({str(k): v for k, v in labels.items()}, ensure_ascii=False), encoding="utf-8")
# Mirror watch.py pattern: gate to_html so core outputs (graph.json +
# GRAPH_REPORT.md) always land. Honor --no-viz explicitly; otherwise
@@ -1872,6 +1880,13 @@ def main() -> None:
elif subcmd == "wiki":
from graphify.wiki import to_wiki as _to_wiki
from graphify.analyze import god_nodes as _god_nodes
if not communities:
print(
"error: .graphify_analysis.json is missing or empty — refusing to export wiki to prevent data loss.\n"
"Run `graphify extract .` (or `graphify cluster-only .`) to regenerate community data first.",
file=sys.stderr,
)
sys.exit(1)
if not gods_data:
gods_data = _god_nodes(G)
n = _to_wiki(G, communities, str(out_dir / "wiki"),
+3 -2
View File
@@ -144,9 +144,10 @@ def _call_openai_compat(
try:
from openai import OpenAI
except ImportError as exc:
pkg_hint = "graphifyy[kimi]" if backend == "kimi" else "openai"
raise ImportError(
"Kimi/OpenAI-compatible extraction requires the openai package. "
"Run: pip install openai"
f"{'Ollama' if backend == 'ollama' else 'Kimi'}/OpenAI-compatible extraction requires the openai package. "
f"Run: pip install {pkg_hint}"
) from exc
client = OpenAI(api_key=api_key, base_url=base_url)
+6
View File
@@ -196,6 +196,12 @@ def to_wiki(
out = Path(output_dir)
out.mkdir(parents=True, exist_ok=True)
if not communities:
raise ValueError(
"communities dict is empty — refusing to clear wiki/. "
"Run `graphify extract .` or `graphify cluster-only .` first."
)
# Clear stale .md files from previous runs to prevent orphan accumulation.
# Community labels are LLM-generated (per skill.md Step 5) and non-deterministic
# across runs — the same conceptual community may be named differently each time
+1
View File
@@ -54,6 +54,7 @@ leiden = ["graspologic; python_version < '3.13'"]
office = ["python-docx", "openpyxl"]
video = ["faster-whisper", "yt-dlp"]
kimi = ["openai", "tiktoken"]
ollama = ["openai"]
sql = ["tree-sitter-sql"]
all = ["mcp", "neo4j", "pypdf", "markdownify", "watchdog", "graspologic; python_version < '3.13'", "python-docx", "openpyxl", "faster-whisper", "yt-dlp", "matplotlib", "openai", "tiktoken", "tree-sitter-sql"]