feat(serve): announce get_neighbors/get_community truncation at the top + tests (follow-up to #2069)

This commit is contained in:
safishamsi
2026-07-21 21:39:32 +01:00
parent fef9dbb5e7
commit deb2620be9
2 changed files with 34 additions and 2 deletions
+8 -2
View File
@@ -919,9 +919,15 @@ def _cut_lines_to_budget(lines: list[str], token_budget: int, narrow_hint: str)
cut_at = output[:char_budget].rfind("\n")
cut_at = cut_at if cut_at > 0 else char_budget
kept = output[:cut_at]
cut_count = len(lines) - kept.count("\n") - 1
shown = kept.count("\n") + 1
cut_count = len(lines) - shown
# Announce truncation at the TOP as well, matching _subgraph_to_text — a
# bottom-only marker reads as silence/absence (the BUG-2 fix rationale). The
# notice sits outside char_budget by design (one bounded wrapper line).
return (
kept
f"[!] TRUNCATED: showing {shown} of {len(lines)} lines "
f"(~{token_budget}-token budget). {narrow_hint}\n\n"
+ kept
+ f"\n... (truncated — {cut_count} more lines cut by ~{token_budget}-token budget. "
+ narrow_hint
+ ")"
+26
View File
@@ -25,6 +25,7 @@ from graphify.serve import (
_query_graph_text,
_resolve_context_filters,
_subgraph_to_text,
_cut_lines_to_budget,
_load_graph,
_community_header,
_search_tokens,
@@ -1335,3 +1336,28 @@ def test_subgraph_to_text_order_is_deterministic():
a = _subgraph_to_text(G, nodes, [])
b = _subgraph_to_text(G, set(reversed(list(nodes))), [])
assert a == b
# --- #2069: token budget on get_neighbors / get_community line lists ----------
def test_cut_lines_to_budget_under_budget_is_byte_identical():
lines = ["Neighbors of X:", " --> a [calls] [EXTRACTED]", " --> b [calls] [EXTRACTED]"]
out = _cut_lines_to_budget(lines, token_budget=2000, narrow_hint="use relation_filter")
assert out == "\n".join(lines)
assert "TRUNCATED" not in out and "truncated" not in out
def test_cut_lines_to_budget_over_budget_announces_at_top():
lines = [f" --> node{i} [calls] [EXTRACTED]" for i in range(200)]
out = _cut_lines_to_budget(lines, token_budget=20, narrow_hint="use get_node for a specific symbol")
# Top notice (silence must not read as absence) + accurate counts + bottom marker + hint.
assert out.startswith("[!] TRUNCATED: showing ")
first = out.splitlines()[0]
assert "of 200 lines" in first
assert "use get_node for a specific symbol" in out
assert "truncated" in out # end marker retained
# shown count in the notice matches the actual kept line count.
import re
shown = int(re.search(r"showing (\d+) of", first).group(1))
body = out.split("\n\n", 1)[1].split("\n... (truncated", 1)[0]
assert body.count("\n") + 1 == shown