From 5105c3651a8f1b153a9ce7c1ac327f6933283be3 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Sun, 14 Jun 2026 03:25:49 -0700 Subject: [PATCH] perf(api-server): normalize chat content linearly (#46079) --- gateway/platforms/api_server.py | 12 +++++++++--- tests/gateway/test_api_server_normalize.py | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/gateway/platforms/api_server.py b/gateway/platforms/api_server.py index 1599eda9e6..da86952a09 100644 --- a/gateway/platforms/api_server.py +++ b/gateway/platforms/api_server.py @@ -156,18 +156,23 @@ def _normalize_chat_content( if isinstance(content, list): parts: List[str] = [] + total_len = 0 items = content[:MAX_CONTENT_LIST_SIZE] if len(content) > MAX_CONTENT_LIST_SIZE else content for item in items: if isinstance(item, str): if item: - parts.append(item[:MAX_NORMALIZED_TEXT_LENGTH]) + part = item[:MAX_NORMALIZED_TEXT_LENGTH] + parts.append(part) + total_len += len(part) elif isinstance(item, dict): item_type = str(item.get("type") or "").strip().lower() if item_type in {"text", "input_text", "output_text"}: text = item.get("text", "") if text: try: - parts.append(str(text)[:MAX_NORMALIZED_TEXT_LENGTH]) + part = str(text)[:MAX_NORMALIZED_TEXT_LENGTH] + parts.append(part) + total_len += len(part) except Exception: pass # Silently skip image_url / other non-text parts @@ -175,8 +180,9 @@ def _normalize_chat_content( nested = _normalize_chat_content(item, _max_depth=_max_depth, _depth=_depth + 1) if nested: parts.append(nested) + total_len += len(nested) # Check accumulated size - if sum(len(p) for p in parts) >= MAX_NORMALIZED_TEXT_LENGTH: + if total_len >= MAX_NORMALIZED_TEXT_LENGTH: break result = "\n".join(parts) return result[:MAX_NORMALIZED_TEXT_LENGTH] if len(result) > MAX_NORMALIZED_TEXT_LENGTH else result diff --git a/tests/gateway/test_api_server_normalize.py b/tests/gateway/test_api_server_normalize.py index 2dd2c70f72..1f943ced01 100644 --- a/tests/gateway/test_api_server_normalize.py +++ b/tests/gateway/test_api_server_normalize.py @@ -1,5 +1,6 @@ """Tests for _normalize_chat_content in the API server adapter.""" +from gateway.platforms import api_server from gateway.platforms.api_server import _normalize_chat_content @@ -85,3 +86,19 @@ class TestNormalizeChatContent: def test_empty_list_returns_empty(self): assert _normalize_chat_content([]) == "" + + def test_many_small_parts_normalize_without_quadratic_rescan(self, monkeypatch): + """Large content arrays should normalize in linear time.""" + content = [{"type": "text", "text": "x"} for _ in range(1000)] + sum_calls = 0 + + def counting_sum(values): + nonlocal sum_calls + sum_calls += 1 + return sum(values) + + monkeypatch.setattr(api_server, "sum", counting_sum, raising=False) + result = _normalize_chat_content(content) + + assert result.count("x") == 1000 + assert sum_calls == 0