feat(serve): announce get_neighbors/get_community truncation at the top + tests (follow-up to #2069)
This commit is contained in:
+8
-2
@@ -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
|
||||
+ ")"
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user