From ba460e68384cb274e9f6767d43fb27a5a6b001fc Mon Sep 17 00:00:00 2001 From: ishaan-jaff Date: Mon, 4 Mar 2024 08:20:26 -0800 Subject: [PATCH] (test) claude fixes --- litellm/llms/anthropic.py | 14 +++++++++++++- litellm/tests/test_add_function_to_prompt.py | 3 ++- litellm/tests/test_completion.py | 9 +++------ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/litellm/llms/anthropic.py b/litellm/llms/anthropic.py index 79b84c4d295..44a1b128a96 100644 --- a/litellm/llms/anthropic.py +++ b/litellm/llms/anthropic.py @@ -125,12 +125,19 @@ def completion( format messages for anthropic 1. Anthropic supports roles like "user" and "assistant", (here litellm translates system-> assistant) 2. The first message always needs to be of role "user" + 3. Each message must alternate between "user" and "assistant" (this is not addressed as now by litellm) + 4. final assistant content cannot end with trailing whitespace (anthropic raises an error otherwise) """ # 1. Anthropic only supports roles like "user" and "assistant" - for message in messages: + for idx, message in enumerate(messages): if message["role"] == "system": message["role"] = "assistant" + # if this is the final assistant message, remove trailing whitespace + # TODO: only do this if it's the final assistant message + if message["role"] == "assistant": + message["content"] = message["content"].strip() + # 2. The first message always needs to be of role "user" if len(messages) > 0: if messages[0]["role"] != "user": @@ -211,6 +218,11 @@ def completion( message=str(completion_response["error"]), status_code=response.status_code, ) + elif len(completion_response["content"]) == 0: + raise AnthropicError( + message="No content in response", + status_code=response.status_code, + ) else: text_content = completion_response["content"][0].get("text", None) model_response.choices[0].message.content = text_content # type: ignore diff --git a/litellm/tests/test_add_function_to_prompt.py b/litellm/tests/test_add_function_to_prompt.py index 932e6edd14f..93b09cd8c8b 100644 --- a/litellm/tests/test_add_function_to_prompt.py +++ b/litellm/tests/test_add_function_to_prompt.py @@ -47,8 +47,9 @@ test_function_call_non_openai_model() ## case 2: add_function_to_prompt set def test_function_call_non_openai_model_litellm_mod_set(): litellm.add_function_to_prompt = True + litellm.set_verbose = True try: - model = "claude-instant-1" + model = "claude-instant-1.2" messages = [{"role": "user", "content": "what's the weather in sf?"}] functions = [ { diff --git a/litellm/tests/test_completion.py b/litellm/tests/test_completion.py index bbe1dae3a6a..a9d41be8d14 100644 --- a/litellm/tests/test_completion.py +++ b/litellm/tests/test_completion.py @@ -92,7 +92,6 @@ def test_completion_claude_3(): response = completion( model="anthropic/claude-3-opus-20240229", messages=messages, - max_tokens=10, ) # Add any assertions, here to check response args print(response) @@ -198,19 +197,17 @@ def test_completion_mistral_api_modified_input(): def test_completion_claude2_1(): try: + litellm.set_verbose = True print("claude2.1 test request") messages = [ { "role": "system", - "content": "Your goal is generate a joke on the topic user gives", + "content": "Your goal is generate a joke on the topic user gives.", }, - {"role": "assistant", "content": "Hi, how can i assist you today?"}, {"role": "user", "content": "Generate a 3 liner joke for me"}, ] # test without max tokens - response = completion( - model="claude-2.1", messages=messages, request_timeout=10, max_tokens=10 - ) + response = completion(model="claude-2.1", messages=messages) # Add any assertions here to check the response print(response) print(response.usage)