fix: add missing _parse_response to AzureOpenAIStructuredLLM (#4434)
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Matt Van Horn
Claude Opus 4.6
parent
54bdbde6e6
commit
4437c3e8a8
@@ -1,3 +1,4 @@
|
|||||||
|
import json
|
||||||
import os
|
import os
|
||||||
from typing import Dict, List, Optional
|
from typing import Dict, List, Optional
|
||||||
|
|
||||||
@@ -6,6 +7,7 @@ from openai import AzureOpenAI
|
|||||||
|
|
||||||
from mem0.configs.llms.base import BaseLlmConfig
|
from mem0.configs.llms.base import BaseLlmConfig
|
||||||
from mem0.llms.base import LLMBase
|
from mem0.llms.base import LLMBase
|
||||||
|
from mem0.memory.utils import extract_json
|
||||||
|
|
||||||
SCOPE = "https://cognitiveservices.azure.com/.default"
|
SCOPE = "https://cognitiveservices.azure.com/.default"
|
||||||
|
|
||||||
@@ -83,9 +85,35 @@ class AzureOpenAIStructuredLLM(LLMBase):
|
|||||||
params["tools"] = tools
|
params["tools"] = tools
|
||||||
params["tool_choice"] = tool_choice
|
params["tool_choice"] = tool_choice
|
||||||
|
|
||||||
if tools:
|
|
||||||
params["tools"] = tools
|
|
||||||
params["tool_choice"] = tool_choice
|
|
||||||
|
|
||||||
response = self.client.chat.completions.create(**params)
|
response = self.client.chat.completions.create(**params)
|
||||||
return self._parse_response(response, tools)
|
return self._parse_response(response, tools)
|
||||||
|
|
||||||
|
def _parse_response(self, response, tools):
|
||||||
|
"""
|
||||||
|
Process the response based on whether tools are used or not.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
response: The raw response from API.
|
||||||
|
tools: The list of tools provided in the request.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str or dict: The processed response.
|
||||||
|
"""
|
||||||
|
if tools:
|
||||||
|
processed_response = {
|
||||||
|
"content": response.choices[0].message.content,
|
||||||
|
"tool_calls": [],
|
||||||
|
}
|
||||||
|
|
||||||
|
if response.choices[0].message.tool_calls:
|
||||||
|
for tool_call in response.choices[0].message.tool_calls:
|
||||||
|
processed_response["tool_calls"].append(
|
||||||
|
{
|
||||||
|
"name": tool_call.function.name,
|
||||||
|
"arguments": json.loads(extract_json(tool_call.function.arguments)),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return processed_response
|
||||||
|
else:
|
||||||
|
return response.choices[0].message.content
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
from unittest.mock import Mock
|
||||||
|
|
||||||
from mem0.llms.azure_openai_structured import SCOPE, AzureOpenAIStructuredLLM
|
from mem0.llms.azure_openai_structured import SCOPE, AzureOpenAIStructuredLLM
|
||||||
|
|
||||||
@@ -98,3 +99,75 @@ def test_init_with_placeholder_api_key_uses_default_credential(
|
|||||||
args, kwargs = mock_azure_openai.call_args
|
args, kwargs = mock_azure_openai.call_args
|
||||||
assert kwargs["api_key"] is None
|
assert kwargs["api_key"] is None
|
||||||
assert kwargs["azure_ad_token_provider"] == "token-provider"
|
assert kwargs["azure_ad_token_provider"] == "token-provider"
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch("mem0.llms.azure_openai_structured.AzureOpenAI")
|
||||||
|
def test_generate_response_without_tools(mock_azure_openai):
|
||||||
|
mock_client = Mock()
|
||||||
|
mock_azure_openai.return_value = mock_client
|
||||||
|
|
||||||
|
config = DummyConfig(model="test-model", azure_kwargs=DummyAzureKwargs(api_key="real-key"))
|
||||||
|
llm = AzureOpenAIStructuredLLM(config)
|
||||||
|
|
||||||
|
mock_response = Mock()
|
||||||
|
mock_response.choices = [Mock(message=Mock(content="Hello there!"))]
|
||||||
|
mock_client.chat.completions.create.return_value = mock_response
|
||||||
|
|
||||||
|
messages = [{"role": "user", "content": "Hi"}]
|
||||||
|
response = llm.generate_response(messages)
|
||||||
|
|
||||||
|
assert response == "Hello there!"
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch("mem0.llms.azure_openai_structured.AzureOpenAI")
|
||||||
|
def test_generate_response_with_tools(mock_azure_openai):
|
||||||
|
mock_client = Mock()
|
||||||
|
mock_azure_openai.return_value = mock_client
|
||||||
|
|
||||||
|
config = DummyConfig(model="test-model", azure_kwargs=DummyAzureKwargs(api_key="real-key"))
|
||||||
|
llm = AzureOpenAIStructuredLLM(config)
|
||||||
|
|
||||||
|
mock_tool_call = Mock()
|
||||||
|
mock_tool_call.function.name = "add_memory"
|
||||||
|
mock_tool_call.function.arguments = '{"data": "sunny day"}'
|
||||||
|
|
||||||
|
mock_message = Mock()
|
||||||
|
mock_message.content = "I've added the memory."
|
||||||
|
mock_message.tool_calls = [mock_tool_call]
|
||||||
|
|
||||||
|
mock_response = Mock()
|
||||||
|
mock_response.choices = [Mock(message=mock_message)]
|
||||||
|
mock_client.chat.completions.create.return_value = mock_response
|
||||||
|
|
||||||
|
tools = [{"type": "function", "function": {"name": "add_memory"}}]
|
||||||
|
messages = [{"role": "user", "content": "Remember sunny day"}]
|
||||||
|
response = llm.generate_response(messages, tools=tools)
|
||||||
|
|
||||||
|
assert response["content"] == "I've added the memory."
|
||||||
|
assert len(response["tool_calls"]) == 1
|
||||||
|
assert response["tool_calls"][0]["name"] == "add_memory"
|
||||||
|
assert response["tool_calls"][0]["arguments"] == {"data": "sunny day"}
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch("mem0.llms.azure_openai_structured.AzureOpenAI")
|
||||||
|
def test_generate_response_with_tools_no_tool_calls(mock_azure_openai):
|
||||||
|
mock_client = Mock()
|
||||||
|
mock_azure_openai.return_value = mock_client
|
||||||
|
|
||||||
|
config = DummyConfig(model="test-model", azure_kwargs=DummyAzureKwargs(api_key="real-key"))
|
||||||
|
llm = AzureOpenAIStructuredLLM(config)
|
||||||
|
|
||||||
|
mock_message = Mock()
|
||||||
|
mock_message.content = "No tools needed."
|
||||||
|
mock_message.tool_calls = None
|
||||||
|
|
||||||
|
mock_response = Mock()
|
||||||
|
mock_response.choices = [Mock(message=mock_message)]
|
||||||
|
mock_client.chat.completions.create.return_value = mock_response
|
||||||
|
|
||||||
|
tools = [{"type": "function", "function": {"name": "add_memory"}}]
|
||||||
|
messages = [{"role": "user", "content": "Hello"}]
|
||||||
|
response = llm.generate_response(messages, tools=tools)
|
||||||
|
|
||||||
|
assert response["content"] == "No tools needed."
|
||||||
|
assert response["tool_calls"] == []
|
||||||
|
|||||||
Reference in New Issue
Block a user