From 2de6c760552f6a7dde302bdf2093473af91b863e Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Tue, 20 Oct 2026 20:43:03 -0700 Subject: [PATCH] chore(count_tokens): give the picked token counter lines type-discipline reasons on stable/1.104.x --- .../prompt_templates/chat_template_tools.py | 7 ++++++- litellm/litellm_core_utils/token_counter.py | 20 ++++++++++--------- litellm/utils.py | 2 +- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/litellm/litellm_core_utils/prompt_templates/chat_template_tools.py b/litellm/litellm_core_utils/prompt_templates/chat_template_tools.py index 60134456577..62b68314d8f 100644 --- a/litellm/litellm_core_utils/prompt_templates/chat_template_tools.py +++ b/litellm/litellm_core_utils/prompt_templates/chat_template_tools.py @@ -18,7 +18,12 @@ def _deepseek_v4_tool_schemas(functions: Sequence[Mapping[str, object]]) -> str: def _qwen3_5_tool_schemas(functions: Sequence[Mapping[str, object]]) -> str: return "".join( - "\n" + json.dumps({"type": "function", "function": function}, ensure_ascii=False) for function in functions + "\n" + + json.dumps( + {"type": "function", "function": function}, # mutable-ok: serialized at once + ensure_ascii=False, + ) + for function in functions ) diff --git a/litellm/litellm_core_utils/token_counter.py b/litellm/litellm_core_utils/token_counter.py index 3ea9dea5631..e5497177f17 100644 --- a/litellm/litellm_core_utils/token_counter.py +++ b/litellm/litellm_core_utils/token_counter.py @@ -1049,7 +1049,7 @@ def _is_anthropic_web_search_tool(tool: Mapping[str, object]) -> bool: def _tool_mappings(tools: Sequence[object]) -> Iterable[Mapping[str, object]]: for tool in tools: if isinstance(tool, Mapping): - yield cast(Mapping[str, object], tool) + yield cast(Mapping[str, object], tool) # cast-ok: tool payloads are JSON objects with str keys def _function_definitions(tools: Sequence[object]) -> Iterable[Mapping[str, object]]: @@ -1069,20 +1069,22 @@ def _function_definitions_for_tool(tool: Mapping[str, object]) -> Iterable[Mappi yield declaration return input_schema: Final = tool.get("input_schema") - parameters: Final = input_schema or tool.get("parameters") or {} - normalized_parameters: Final = parameters if isinstance(parameters, Mapping) else {} + parameters: Final = input_schema or tool.get("parameters") or {} # mutable-ok: read-only default + normalized_parameters: Final = parameters if isinstance(parameters, Mapping) else {} # mutable-ok: never mutated unmapped_anthropic_keys: Final = ( - {key: value for key, value in tool.items() if key not in _ANTHROPIC_TOOL_KEYS_MAPPED_BY_BRIDGE} + { # mutable-ok: never mutated + key: value for key, value in tool.items() if key not in _ANTHROPIC_TOOL_KEYS_MAPPED_BY_BRIDGE + } if input_schema is not None - else {} + else {} # mutable-ok: read-only default ) description: Final = tool.get("description") strict: Final = tool.get("strict") - yield { + yield { # mutable-ok: yielded as a read-only Mapping "name": tool.get("name"), - "parameters": {**normalized_parameters, **unmapped_anthropic_keys}, - **({"description": description} if description is not None else {}), - **({"strict": bool(strict)} if strict is not None else {}), + "parameters": {**normalized_parameters, **unmapped_anthropic_keys}, # mutable-ok: never mutated + **({"description": description} if description is not None else {}), # mutable-ok: spread at once + **({"strict": bool(strict)} if strict is not None else {}), # mutable-ok: spread at once } diff --git a/litellm/utils.py b/litellm/utils.py index 5f922746fa2..09d0a4fa7f6 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -2453,7 +2453,7 @@ def _return_huggingface_tokenizer(model: str, *, count_route: bool = False) -> S def _huggingface_tokenizer(kind: HuggingFaceTokenizerKind) -> SelectTokenizerResponse: with _BUNDLED_TOKENIZER_LOAD_LOCKS.get(kind, nullcontext()): tokenizer: Final = _load_huggingface_tokenizer(kind, _huggingface_tokenizer_backend()) - return {"type": "huggingface_tokenizer", "tokenizer": tokenizer} + return {"type": "huggingface_tokenizer", "tokenizer": tokenizer} # mutable-ok: SelectTokenizerResponse shape def select_count_route_tokenizer(