diff --git a/litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py b/litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py index b8370d5fef2..67b7fa749a7 100644 --- a/litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py +++ b/litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py @@ -1022,7 +1022,7 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig): if "functionCall" in part: _function_chunk = ChatCompletionToolCallFunctionChunk( name=part["functionCall"]["name"], - arguments=json.dumps(part["functionCall"]["args"]), + arguments=json.dumps(part["functionCall"]["args"], ensure_ascii=False), ) if is_function_call is True: function = _function_chunk diff --git a/tests/llm_translation/test_gemini.py b/tests/llm_translation/test_gemini.py index b7628a49039..3b33b6a346a 100644 --- a/tests/llm_translation/test_gemini.py +++ b/tests/llm_translation/test_gemini.py @@ -1135,3 +1135,72 @@ def test_gemini_embedding(): ) print("response: ", response) assert response is not None + + +def test_gemini_function_args_preserve_unicode(): + """ + Test for Issue #16533: Gemini function call arguments should preserve non-ASCII characters + https://github.com/BerriAI/litellm/issues/16533 + + Before fix: "や" becomes "\u3084" + After fix: "や" stays as "や" + """ + from litellm.llms.vertex_ai.gemini.vertex_and_google_ai_studio_gemini import VertexGeminiConfig + + # Test Japanese characters + parts = [ + { + "functionCall": { + "name": "send_message", + "args": { + "message": "やあ", # Japanese "hello" + "recipient": "たけし" # Japanese name + } + } + } + ] + + function, tools, _ = VertexGeminiConfig._transform_parts( + parts=parts, + cumulative_tool_call_idx=0, + is_function_call=False + ) + + arguments_str = tools[0]['function']['arguments'] + parsed_args = json.loads(arguments_str) + + # Verify characters are preserved + assert parsed_args["message"] == "やあ", "Japanese characters should be preserved" + assert parsed_args["recipient"] == "たけし", "Japanese characters should be preserved" + + # Verify no Unicode escape sequences in raw string + assert "\\u" not in arguments_str, "Should not contain Unicode escape sequences" + assert "やあ" in arguments_str, "Original Japanese characters should be in the string" + assert "たけし" in arguments_str, "Original Japanese characters should be in the string" + + # Test Spanish characters + parts_spanish = [ + { + "functionCall": { + "name": "send_message", + "args": { + "message": "¡Hola! ¿Cómo estás?", + "recipient": "José" + } + } + } + ] + + function, tools, _ = VertexGeminiConfig._transform_parts( + parts=parts_spanish, + cumulative_tool_call_idx=0, + is_function_call=False + ) + + arguments_str = tools[0]['function']['arguments'] + parsed_args = json.loads(arguments_str) + + assert parsed_args["message"] == "¡Hola! ¿Cómo estás?" + assert parsed_args["recipient"] == "José" + assert "\\u" not in arguments_str + assert "José" in arguments_str