fix: do not load the anthropic package on import

`serena.analytics` imported `anthropic.types` at module level for two type
annotations, so every `import serena.cli` / `import serena.agent` paid for
loading the whole anthropic package (2-4 s on the reporter's Windows machine)
even with the default CHAR_COUNT token estimator. That delay can push MCP
startup past a client's initial tool-discovery window.

The import now lives behind `TYPE_CHECKING`; `AnthropicTokenCount` already
imported `anthropic` lazily in `__init__`, and the request body is a plain
dict (what `MessageParam` produces at runtime anyway).

Tests: importing serena.cli / serena.agent / serena.analytics in a fresh
interpreter leaves `anthropic` out of `sys.modules`; the Anthropic estimator
still sends the expected count_tokens request.

Fixes #2012
This commit is contained in:
L4XB authored and Dr. Dominik Jain committed 2026-09-16 02:22:00 +02:00
1 parent 922cac9da4
commit 16322651bb
3 files changed
+38 -2

No files matched your search

+29
View File
@@ -0,0 +1,29 @@
"""The anthropic package must only be loaded when the Anthropic token counter is used (#2012)."""
import subprocess
import sys
from unittest.mock import MagicMock
import pytest
from serena.analytics import AnthropicTokenCount
@pytest.mark.parametrize("module", ["serena.cli", "serena.agent", "serena.analytics"])
def test_importing_serena_does_not_load_anthropic(module: str) -> None:
code = f"import sys, {module}; print('anthropic' in sys.modules)"
result = subprocess.run([sys.executable, "-c", code], capture_output=True, text=True, check=True, timeout=120)
assert result.stdout.strip() == "False", f"importing {module} loaded the anthropic package"
def test_anthropic_token_count_sends_a_plain_user_message() -> None:
estimator = AnthropicTokenCount.__new__(AnthropicTokenCount)
estimator._model_name = "claude-sonnet-4-20250514"
estimator._anthropic_client = MagicMock()
estimator._anthropic_client.messages.count_tokens.return_value = MagicMock(input_tokens=7)
assert estimator.estimate_token_count("hello") == 7
estimator._anthropic_client.messages.count_tokens.assert_called_once_with(
model="claude-sonnet-4-20250514",
messages=[{"role": "user", "content": "hello"}],
)