From 21d08c8482104d672eaf92ce4e3721b6e2c627d8 Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Sun, 1 Nov 2026 09:14:06 -0800 Subject: [PATCH] fix(anthropic): decode text attachments under every WHATWG label Python knows The allowlist kept Python codec names for one label per WHATWG encoding, so labels that Python maps to a codec of its own (iso-8859-9, iso-8859-11, tis-620, gb2312, big5-hkscs, ms932) answered 400 instead of decoding. All six are linear table codecs, so the punycode and utf-7 rejection stands --- .../litellm_core_utils/prompt_templates/factory.py | 6 +++++- ...t_litellm_core_utils_prompt_templates_factory.py | 13 ++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/litellm/litellm_core_utils/prompt_templates/factory.py b/litellm/litellm_core_utils/prompt_templates/factory.py index 1170dca53d8..3ee61a9a94a 100644 --- a/litellm/litellm_core_utils/prompt_templates/factory.py +++ b/litellm/litellm_core_utils/prompt_templates/factory.py @@ -1868,18 +1868,22 @@ _TEXT_ATTACHMENT_ENCODINGS: Final = frozenset( "utf-16-be", "ascii", "latin-1", - *(f"iso8859-{part}" for part in (2, 3, 4, 5, 6, 7, 8, 10, 13, 14, 15, 16)), + *(f"iso8859-{part}" for part in (*range(2, 12), *range(13, 17))), + "tis-620", *(f"cp{code_page}" for code_page in (866, 874, *range(1250, 1259))), "koi8-r", "koi8-u", "mac-roman", "mac-cyrillic", + "gb2312", "gbk", "gb18030", "big5", + "big5hkscs", "euc-jp", "iso2022-jp", "shift-jis", + "cp932", "euc-kr", ) ) diff --git a/tests/unit/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_factory.py b/tests/unit/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_factory.py index a3e802e97a4..c8d53c12aaf 100644 --- a/tests/unit/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_factory.py +++ b/tests/unit/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_factory.py @@ -9383,7 +9383,18 @@ def test_anthropic_messages_pt_text_document_keeps_charset_named_by_the_data_uri @pytest.mark.parametrize( ("charset", "text"), - [("shift_jis", "日本語"), ("windows-1252", "café"), ("KOI8-R", "привет"), ("utf-16", "naïve")], + [ + ("shift_jis", "日本語"), + ("windows-1252", "café"), + ("KOI8-R", "привет"), + ("utf-16", "naïve"), + ("iso-8859-9", "İstanbul"), + ("iso-8859-11", "ไทย"), + ("tis-620", "ไทย"), + ("gb2312", "中文"), + ("big5-hkscs", "香港"), + ("ms932", "日本語"), + ], ) def test_anthropic_messages_pt_reads_a_text_attachment_in_a_legacy_encoding_its_data_uri_names(charset, text): data_uri: Final = f"data:text/plain;charset={charset};base64," + base64.b64encode(text.encode(charset)).decode()