Skip to content

ccproxy.llms.utils.token_estimation

ccproxy.llms.utils.token_estimation

Token estimation utilities for context window management.

estimate_tokens

estimate_tokens(content)

Estimate token count for content.

Uses ~3 characters per token heuristic for English text. This is a conservative estimate - actual may be lower.

Parameters:

Name Type Description Default
content Any

Message content (string, list of blocks, or dict)

required

Returns:

Type Description
int

Estimated token count

Source code in ccproxy/llms/utils/token_estimation.py
def estimate_tokens(content: Any) -> int:
    """Estimate token count for content.

    Uses ~3 characters per token heuristic for English text.
    This is a conservative estimate - actual may be lower.

    Args:
        content: Message content (string, list of blocks, or dict)

    Returns:
        Estimated token count
    """
    if content is None:
        return 0

    if isinstance(content, str):
        # ~3 chars per token for English, be conservative
        return max(1, len(content) // 3)

    if isinstance(content, list):
        total = 0
        for block in content:
            if isinstance(block, dict):
                block_type = block.get("type", "")
                if block_type == "text":
                    total += estimate_tokens(block.get("text", ""))
                elif block_type == "tool_use":
                    # Tool name + input
                    total += estimate_tokens(block.get("name", ""))
                    total += estimate_tokens(json.dumps(block.get("input", {})))
                elif block_type == "tool_result":
                    total += estimate_tokens(block.get("content", ""))
                elif block_type == "image":
                    # Images are ~1600 tokens for typical size
                    total += 1600
                else:
                    # Generic block - serialize and estimate
                    total += estimate_tokens(json.dumps(block))
            else:
                total += estimate_tokens(block)
        return total

    if isinstance(content, dict):
        return estimate_tokens(json.dumps(content))

    return estimate_tokens(str(content))

estimate_messages_tokens

estimate_messages_tokens(messages)

Estimate total tokens for a list of messages.

Parameters:

Name Type Description Default
messages list[dict[str, Any]]

List of message dicts with role and content

required

Returns:

Type Description
int

Estimated total token count

Source code in ccproxy/llms/utils/token_estimation.py
def estimate_messages_tokens(messages: list[dict[str, Any]]) -> int:
    """Estimate total tokens for a list of messages.

    Args:
        messages: List of message dicts with role and content

    Returns:
        Estimated total token count
    """
    total = 0
    for msg in messages:
        # Role contributes ~2 tokens
        total += 2
        total += estimate_tokens(msg.get("content"))
    return total

estimate_request_tokens

estimate_request_tokens(request_data)

Estimate total input tokens for a request.

Includes messages, system prompt, and tool definitions.

Parameters:

Name Type Description Default
request_data dict[str, Any]

The request payload dictionary

required

Returns:

Type Description
int

Estimated total input token count

Source code in ccproxy/llms/utils/token_estimation.py
def estimate_request_tokens(request_data: dict[str, Any]) -> int:
    """Estimate total input tokens for a request.

    Includes messages, system prompt, and tool definitions.

    Args:
        request_data: The request payload dictionary

    Returns:
        Estimated total input token count
    """
    total = 0

    # Messages
    messages = request_data.get("messages", [])
    total += estimate_messages_tokens(messages)

    # System prompt
    system = request_data.get("system")
    if system:
        total += estimate_tokens(system)

    # Tools
    tools = request_data.get("tools", [])
    if tools:
        total += estimate_tokens(json.dumps(tools))

    return total

get_max_input_tokens

get_max_input_tokens(model)

Get max input tokens for a model.

Supports pattern matching for model variants: - Exact match: "claude-opus-4-5-20251101" - Prefix match: "claude-opus-4-5-*" matches "claude-opus-4-5-20251101"

Parameters:

Name Type Description Default
model str

Model name or identifier

required

Returns:

Type Description
int | None

Max input tokens if known, None otherwise

Source code in ccproxy/llms/utils/token_estimation.py
def get_max_input_tokens(model: str) -> int | None:
    """Get max input tokens for a model.

    Supports pattern matching for model variants:
    - Exact match: "claude-opus-4-5-20251101"
    - Prefix match: "claude-opus-4-5-*" matches "claude-opus-4-5-20251101"

    Args:
        model: Model name or identifier

    Returns:
        Max input tokens if known, None otherwise
    """
    limits = _load_token_limits()

    # Try exact match first
    if model in limits:
        return limits[model]

    # Try prefix matching (for patterns like claude-opus-4-5-*)
    for pattern, max_tokens in limits.items():
        if pattern.endswith("*"):
            prefix = pattern[:-1]
            if model.startswith(prefix):
                return max_tokens

    # Try matching known model families
    model_lower = model.lower()
    for known_model, max_tokens in limits.items():
        if known_model.lower() in model_lower or model_lower in known_model.lower():
            return max_tokens

    return None