Skip to content

Commit

Permalink
add tests (#116)
Browse files Browse the repository at this point in the history
  • Loading branch information
TengHu authored Dec 31, 2023
1 parent b5d942b commit cb20275
Show file tree
Hide file tree
Showing 2 changed files with 278 additions and 2 deletions.
2 changes: 1 addition & 1 deletion docs/source/notebooks/cookbooks/logging.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"id": "1b6533b3-44e4-4369-a4db-1d709721d322",
"metadata": {},
"source": [
"# Structured logging & Logging\n",
"# Structured logging & Tracing\n",
"\n",
"This walkthrough guides you through borrowing the simple agent from [quickstart](quickstart.ipynb), and enhancing it with a structured logger. This addition makes it easier to debug, evaluate, and monitor the agent's performance. \n",
"\n",
Expand Down
278 changes: 277 additions & 1 deletion tests/llms/openai/tools/test_chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


class TestOpenAIChatCompletion(unittest.TestCase):
def generate_multiple_mock_function_call_response(self, name, arguments):
def generate_multiple_mock_function_call_response(self, names, arguments):
return ChatCompletion(
**{
"id": "chatcmpl-8WCZDJ12zHTvK8YltBeeDN0NGn0PI",
Expand Down Expand Up @@ -438,6 +438,282 @@ def mock_method(text: str):
),
)

@patch("openai.OpenAI")
def test_patched_create_with_parallel_functions1(self, mock_openai):
client = mock_openai()
mock_create = client.chat.completions.create
client = OpenAIChatCompletion.patch(client)

def mock_method(text: str):
"""mock method"""
return text

actions = [
Action("action1", mock_method).build_pydantic_model_cls(),
]

# Define the expected functions arguments and return values in the API call
expected_functions_and_results = [
(
{
"tools": ["action1"],
"tool_choice": "auto",
},
self.generate_multiple_mock_function_call_response(
["action1", "action1"],
['{\n "text": "echo1"\n}', '{\n "text": "echo2"\n}'],
),
),
(
{
"tools": ["action1"],
"tool_choice": "auto",
},
self.generate_mock_message_response("last message"),
),
]

# Set the return values of the mock
mock_create.side_effect = [
expected_result for _, expected_result in expected_functions_and_results
]

# When
messages = [{"role": "user", "content": "Hi!"}]
response = client.chat.completions.create(
model="test", messages=messages, actions=actions
)

# Then
# Use a loop to iterate over expected calls and assert function arguments in the API call
for i, actual_call in enumerate(mock_create.call_args_list):
if "tools" in actual_call.kwargs:
self.assertEqual(
[tool["function"]["name"] for tool in actual_call.kwargs["tools"]],
expected_functions_and_results[i][0]["tools"],
)
self.assertEqual(
actual_call.kwargs["tool_choice"],
expected_functions_and_results[i][0]["tool_choice"],
)
else:
self.assertFalse("tools" in expected_functions_and_results[i][0])
self.assertFalse("tool_choice" in expected_functions_and_results[i][0])

self.assertEqual(
messages,
[
{"content": "Hi!", "role": "user"},
ChatCompletionMessage(
content=None,
role="assistant",
function_call=None,
tool_calls=[
ChatCompletionMessageToolCall(
id="call_70TwJYHkDSs80tcnF5lt8TQR",
function=Function(
arguments='{\n "text": "echo1"\n}', name="action1"
),
type="function",
),
ChatCompletionMessageToolCall(
id="call_70TwJYHkDSs80tcnF5lt8TQR",
function=Function(
arguments='{\n "text": "echo2"\n}', name="action1"
),
type="function",
),
],
),
{
"content": "echo1",
"name": "action1",
"role": "tool",
"tool_call_id": "call_70TwJYHkDSs80tcnF5lt8TQR",
},
{
"content": "echo2",
"name": "action1",
"role": "tool",
"tool_call_id": "call_70TwJYHkDSs80tcnF5lt8TQR",
},
],
)

self.assertEqual(
response,
ChatCompletion(
id="chatcmpl-8WCdHNVdrYkU8cir7xYcji02Lenuw",
choices=[
Choice(
finish_reason="stop",
index=0,
logprobs=None,
message=ChatCompletionMessage(
content="last message",
role="assistant",
function_call=None,
tool_calls=None,
),
)
],
created=1702685747,
model="gpt-3.5-turbo-1106",
object="chat.completion",
system_fingerprint="fp_772e8125bb",
usage=CompletionUsage(
completion_tokens=35, prompt_tokens=27, total_tokens=62
),
),
)

@patch("openai.OpenAI")
def test_patched_create_with_parallel_functions2(self, mock_openai):
client = mock_openai()
mock_create = client.chat.completions.create
client = OpenAIChatCompletion.patch(client)

def mock_method(text: str):
"""mock method"""
return text

actions = [
Action("action1", mock_method).build_pydantic_model_cls(),
Action("action2", mock_method).build_pydantic_model_cls(),
]

# Define the expected functions arguments and return values in the API call
expected_functions_and_results = [
(
{
"tools": ["action1", "action2"],
"tool_choice": "auto",
},
self.generate_multiple_mock_function_call_response(
["action1", "action1", "action2"],
[
'{\n "text": "echo1"\n}',
'{\n "text": "echo2"\n}',
'{\n "text": "echo3"\n}',
],
),
),
(
{
"tools": ["action1", "action2"],
"tool_choice": "auto",
},
self.generate_mock_message_response("last message"),
),
]

# Set the return values of the mock
mock_create.side_effect = [
expected_result for _, expected_result in expected_functions_and_results
]

# When
messages = [{"role": "user", "content": "Hi!"}]
response = client.chat.completions.create(
model="test", messages=messages, actions=actions
)

# Then
# Use a loop to iterate over expected calls and assert function arguments in the API call
for i, actual_call in enumerate(mock_create.call_args_list):
if "tools" in actual_call.kwargs:
self.assertEqual(
[tool["function"]["name"] for tool in actual_call.kwargs["tools"]],
expected_functions_and_results[i][0]["tools"],
)
self.assertEqual(
actual_call.kwargs["tool_choice"],
expected_functions_and_results[i][0]["tool_choice"],
)
else:
self.assertFalse("tools" in expected_functions_and_results[i][0])
self.assertFalse("tool_choice" in expected_functions_and_results[i][0])

self.assertEqual(
messages,
[
{"content": "Hi!", "role": "user"},
ChatCompletionMessage(
content=None,
role="assistant",
function_call=None,
tool_calls=[
ChatCompletionMessageToolCall(
id="call_70TwJYHkDSs80tcnF5lt8TQR",
function=Function(
arguments='{\n "text": "echo1"\n}', name="action1"
),
type="function",
),
ChatCompletionMessageToolCall(
id="call_70TwJYHkDSs80tcnF5lt8TQR",
function=Function(
arguments='{\n "text": "echo2"\n}', name="action1"
),
type="function",
),
ChatCompletionMessageToolCall(
id="call_70TwJYHkDSs80tcnF5lt8TQR",
function=Function(
arguments='{\n "text": "echo3"\n}', name="action2"
),
type="function",
),
],
),
{
"content": "echo1",
"name": "action1",
"role": "tool",
"tool_call_id": "call_70TwJYHkDSs80tcnF5lt8TQR",
},
{
"content": "echo2",
"name": "action1",
"role": "tool",
"tool_call_id": "call_70TwJYHkDSs80tcnF5lt8TQR",
},
{
"content": "echo3",
"name": "action2",
"role": "tool",
"tool_call_id": "call_70TwJYHkDSs80tcnF5lt8TQR",
},
],
)

self.assertEqual(
response,
ChatCompletion(
id="chatcmpl-8WCdHNVdrYkU8cir7xYcji02Lenuw",
choices=[
Choice(
finish_reason="stop",
index=0,
logprobs=None,
message=ChatCompletionMessage(
content="last message",
role="assistant",
function_call=None,
tool_calls=None,
),
)
],
created=1702685747,
model="gpt-3.5-turbo-1106",
object="chat.completion",
system_fingerprint="fp_772e8125bb",
usage=CompletionUsage(
completion_tokens=35, prompt_tokens=27, total_tokens=62
),
),
)

### Tests for actionweaver.llms.openai.tools.chat.OpenAIChatCompletion

@patch("openai.resources.chat.Completions.create")
Expand Down

0 comments on commit cb20275

Please sign in to comment.