fix(mcp): make list-item truncation cap configurable in get_dashboard_info (#41698)

(cherry picked from commit 62ccdfacc2)
This commit is contained in:
Amin Ghadersohi
2026-07-13 14:46:10 -04:00
committed by Joe Li
parent 9ee3272399
commit ff2ebcfdfb
11 changed files with 284 additions and 11 deletions

View File

@@ -677,3 +677,75 @@ class TestTruncateOversizedResponse:
assert isinstance(result, dict)
assert result["id"] == 1 # Scalar fields preserved
assert len(notes) > 0
@staticmethod
def _build_large_dashboard_response() -> dict[str, Any]:
"""A dashboard with 463 charts and 48 native_filters, shared by the
default- and custom-max_list_items regression tests below."""
return {
"id": 1,
"dashboard_title": "x" * 2000, # forces Phase 2 to trigger
"charts": [{"id": i, "slice_name": f"chart_{i}"} for i in range(463)],
"native_filters": [{"id": i, "name": f"filter_{i}"} for i in range(48)],
}
def test_large_dashboard_respects_default_max_list_items(self) -> None:
"""Regression test for the Medialab large-dashboard report.
A dashboard with 463 charts and 48 native_filters should have
native_filters (48 items) left untouched under the new default cap
of 100, while charts (463 items) is truncated to 100 — a clear
improvement over the old flat 30-item cap, which truncated both.
"""
response: dict[str, Any] = self._build_large_dashboard_response()
result: Any
was_truncated: bool
notes: list[str]
result, was_truncated, notes = truncate_oversized_response(response, 3000)
assert was_truncated is True
assert isinstance(result, dict)
assert len(result["charts"]) == 100
assert len(result["native_filters"]) == 48
assert any("charts" in n and "463" in n for n in notes)
assert not any("native_filters" in n for n in notes)
def test_large_dashboard_respects_custom_max_list_items(self) -> None:
"""A custom max_list_items below both list sizes should truncate both fields."""
response: dict[str, Any] = self._build_large_dashboard_response()
result: Any
was_truncated: bool
notes: list[str]
result, was_truncated, notes = truncate_oversized_response(
response, 3000, max_list_items=30
)
assert was_truncated is True
assert isinstance(result, dict)
assert len(result["charts"]) == 30
assert len(result["native_filters"]) == 30
assert any("charts" in n and "30" in n for n in notes)
assert any("native_filters" in n and "30" in n for n in notes)
def test_custom_max_list_items_below_phase_four_survives_phase_four(self) -> None:
"""A max_list_items below Phase 4's hardcoded 10 should not be widened.
Phase 2 truncates ``charts`` to 5 first; the response is still over
budget because of the oversized ``form_data`` dict, so truncation
proceeds to Phase 4, whose ``_truncate_lists(..., max_items=10)``
call only shrinks lists larger than 10 — it must leave the
already-smaller 5-item list untouched rather than re-expanding it.
"""
response: dict[str, Any] = {
"id": 1,
"charts": [{"id": i, "slice_name": f"chart_{i}"} for i in range(300)],
"form_data": {f"key_{i}": f"val_{i}" for i in range(50)},
}
result: Any
was_truncated: bool
notes: list[str]
result, was_truncated, notes = truncate_oversized_response(
response, 200, max_list_items=5
)
assert was_truncated is True
assert isinstance(result, dict)
assert len(result["charts"]) == 5
assert any("form_data" in n for n in notes)