Files
graphify/tests/test_label_retry.py
Safi ab1e0ec588 Adaptive split-and-retry for community labeling on parse failure (#1280, #1278)
label_communities logged-and-skipped any batch whose LLM response was malformed
JSON, silently losing ~100 names per failed batch on large graphs. Split the
batch at the midpoint and retry each half (smaller prompt -> smaller output),
mirroring _extract_with_adaptive_retry; the base case re-raises so the caller
skips just that batch. Removed leftover scaffolding and corrected the docstring.

Co-Authored-By: CJdev232 <CJdev232@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 22:50:52 +01:00

47 lines
1.7 KiB
Python

"""Tests for graphify.llm._label_batch_with_retry — adaptive split-and-retry
on JSON parse failure during community labeling (#1278).
"""
from __future__ import annotations
import json
import re
from graphify import llm as llm_mod
def test_label_batch_recovers_via_split_on_invalid_json(monkeypatch):
"""Demonstrates the bug fix.
The full batch of 4 communities triggers malformed JSON from the LLM.
The helper splits in half (2+2) and retries each half. Both sub-batches
succeed. Every community ends up labeled — none silently dropped.
"""
batch_cids = [42, 99, 137, 201]
batch_lines = [
"Community 42: validate_token, get_session",
"Community 99: create_order, add_to_cart",
"Community 137: build_graph, cluster_nodes",
"Community 201: render_route, handle_request",
]
call_count = {"n": 0}
def fake_call_llm(prompt: str, **_kwargs) -> str:
"""First call (4 communities): returns broken JSON to trigger retry.
Subsequent calls (<=2 communities): return a clean JSON object
labeling whatever community IDs appear in the prompt.
"""
call_count["n"] += 1
cids_in_prompt = [int(m) for m in re.findall(r"Community (\d+):", prompt)]
if call_count["n"] == 1:
return "{this is not valid json, missing quotes"
return json.dumps({str(cid): f"Label {cid}" for cid in cids_in_prompt})
monkeypatch.setattr(llm_mod, "_call_llm", fake_call_llm)
result = llm_mod._label_batch_with_retry(
batch_cids, batch_lines, backend="gemini", model=None,
)
assert result == {42: "Label 42", 99: "Label 99", 137: "Label 137", 201: "Label 201"}
assert call_count["n"] >= 2