diff --git a/docs/my-website/docs/count_tokens.md b/docs/my-website/docs/count_tokens.md index ce295514141..108e2e650f2 100644 --- a/docs/my-website/docs/count_tokens.md +++ b/docs/my-website/docs/count_tokens.md @@ -65,11 +65,13 @@ async def main(): messages=[{"role": "user", "content": "What's the weather in Paris?"}], tools=[{ "type": "function", - "name": "get_weather", - "description": "Get weather for a city", - "parameters": { - "type": "object", - "properties": {"city": {"type": "string"}}, + "function": { + "name": "get_weather", + "description": "Get weather for a city", + "parameters": { + "type": "object", + "properties": {"city": {"type": "string"}}, + }, }, }], system="You are a helpful weather assistant.", diff --git a/litellm/llms/openai/chat/gpt_transformation.py b/litellm/llms/openai/chat/gpt_transformation.py index fafd37f9611..d19210d31ab 100644 --- a/litellm/llms/openai/chat/gpt_transformation.py +++ b/litellm/llms/openai/chat/gpt_transformation.py @@ -58,6 +58,7 @@ from ..common_utils import OpenAIError if TYPE_CHECKING: from litellm.litellm_core_utils.litellm_logging import Logging as _LiteLLMLoggingObj + from litellm.llms.base_llm.base_utils import BaseTokenCounter from litellm.types.llms.openai import ChatCompletionToolParam LiteLLMLoggingObj = _LiteLLMLoggingObj diff --git a/litellm/llms/openai/responses/count_tokens/token_counter.py b/litellm/llms/openai/responses/count_tokens/token_counter.py index 65eb2fc62fa..3d3a659075e 100644 --- a/litellm/llms/openai/responses/count_tokens/token_counter.py +++ b/litellm/llms/openai/responses/count_tokens/token_counter.py @@ -68,6 +68,10 @@ class OpenAITokenCounter(BaseTokenCounter): if instructions is None and system is not None: instructions = system if isinstance(system, str) else str(system) + # If no input items were produced (e.g., system-only messages), fall back to local counting + if not input_items: + return None + try: result = await openai_count_tokens_handler.handle_count_tokens_request( model=model_to_use, diff --git a/litellm/llms/openai/responses/count_tokens/transformation.py b/litellm/llms/openai/responses/count_tokens/transformation.py index 282f530791f..3893775fc01 100644 --- a/litellm/llms/openai/responses/count_tokens/transformation.py +++ b/litellm/llms/openai/responses/count_tokens/transformation.py @@ -75,12 +75,15 @@ class OpenAICountTokensConfig: for tool in tools: if tool.get("type") == "function" and "function" in tool: func = tool["function"] - transformed.append({ + item: Dict[str, Any] = { "type": "function", "name": func.get("name", ""), "description": func.get("description", ""), "parameters": func.get("parameters", {}), - }) + } + if "strict" in func: + item["strict"] = func["strict"] + transformed.append(item) else: # Pass through non-function tools (e.g., web_search, file_search) transformed.append(tool) diff --git a/litellm/proxy/response_api_endpoints/endpoints.py b/litellm/proxy/response_api_endpoints/endpoints.py index aa5298c2cc1..b694b31979c 100644 --- a/litellm/proxy/response_api_endpoints/endpoints.py +++ b/litellm/proxy/response_api_endpoints/endpoints.py @@ -417,7 +417,6 @@ async def cursor_chat_completions( ) async def count_response_input_tokens( request: Request, - user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), ): """ Count input tokens for OpenAI Responses API format.