From f41b19a120338856f697790766a0c934d7f7b1ec Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Fri, 4 Sep 2026 19:17:58 -0700 Subject: [PATCH] fix(ci): cap each sync PR body section so a large first sync stays under GitHub's body limit --- scripts/sync_cost_map.py | 8 ++++++-- tests/test_litellm/test_sync_cost_map.py | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/scripts/sync_cost_map.py b/scripts/sync_cost_map.py index bd75cb2000a..50f85eee64f 100644 --- a/scripts/sync_cost_map.py +++ b/scripts/sync_cost_map.py @@ -36,6 +36,7 @@ OPENROUTER_MODELS_URL: Final = "https://openrouter.ai/api/v1/models" VERCEL_MODELS_URL: Final = "https://ai-gateway.vercel.sh/v1/models" VERCEL_TYPE_TO_MODE: Final = MappingProxyType({"language": "chat", "embedding": "embedding"}) ADD_ONLY_FIELDS: Final = frozenset({"max_output_tokens", "max_tokens"}) +PR_BODY_SECTION_LIMIT: Final = 30 Provider = Literal["openrouter", "vercel_ai_gateway"] RegistryEntry = dict[str, object] @@ -385,8 +386,11 @@ def _ordered_result(cost_map: CostMap, result: CostMap, outcomes: Sequence[Provi def _section_block(title: str, lines: Sequence[str], backtick: bool) -> str: - bullets: Final = "\n".join(f"- `{line}`" if backtick else f"- {line}" for line in lines) or "- none" - return f"### {title} ({len(lines)})\n{bullets}\n" + shown: Final = lines[:PR_BODY_SECTION_LIMIT] + bullets: Final = "\n".join(f"- `{line}`" if backtick else f"- {line}" for line in shown) or "- none" + overflow: Final = len(lines) - len(shown) + trailer: Final = f"\n- and {overflow} more, see the diff" if overflow else "" + return f"### {title} ({len(lines)})\n{bullets}{trailer}\n" def _provider_body(outcome: ProviderOutcome) -> str: diff --git a/tests/test_litellm/test_sync_cost_map.py b/tests/test_litellm/test_sync_cost_map.py index eb758d24a83..54946ac86dc 100644 --- a/tests/test_litellm/test_sync_cost_map.py +++ b/tests/test_litellm/test_sync_cost_map.py @@ -264,6 +264,23 @@ def test_pr_body_lists_changes_per_provider(sync: ModuleType) -> None: assert "Catalog rows skipped: deprecated (1), no usable price (1), not token priced (1)" in body +def test_pr_body_caps_every_section_so_a_large_first_sync_fits_github_limit(sync: ModuleType) -> None: + lines: Final = tuple(f"provider/model-{index}: {'x' * 200}" for index in range(400)) + outcome: Final = sync.SyncOutcome( + cost_map={}, + providers=tuple( + sync.ProviderOutcome(provider=provider, added=lines, updated=lines, warnings=lines, skipped={}) + for provider in ("openrouter", "vercel_ai_gateway") + ), + ) + + body: Final = sync.render_pr_body(outcome) + + assert len(body) < 65_536 + assert body.count("### Added (400)") == 2 and body.count("- and 370 more, see the diff") == 6 + assert body.count("- `provider/model-29: ") == 4 and "provider/model-30: " not in body + + @pytest.mark.parametrize( ("loader", "raw"), [