Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions agentops/instrumentation/providers/openai/attributes/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,10 +500,10 @@ def get_response_tools_attributes(tools: List["ToolTypes"]) -> AttributeMap:
def get_response_tool_web_search_attributes(tool: "WebSearchTool", index: int) -> AttributeMap:
"""Handles interpretation of an openai WebSearchTool object."""
parameters = {}
if hasattr(tool, "search_context_size"):
if hasattr(tool, "search_context_size") and tool.search_context_size is not None:
parameters["search_context_size"] = tool.search_context_size

if hasattr(tool, "user_location"):
if hasattr(tool, "user_location") and tool.user_location is not None:
parameters["user_location"] = tool.user_location.__dict__

tool_data = tool.__dict__
Expand All @@ -518,16 +518,16 @@ def get_response_tool_file_search_attributes(tool: "FileSearchTool", index: int)
"""Handles interpretation of an openai FileSearchTool object."""
parameters = {}

if hasattr(tool, "vector_store_ids"):
if hasattr(tool, "vector_store_ids") and tool.vector_store_ids is not None:
parameters["vector_store_ids"] = tool.vector_store_ids

if hasattr(tool, "filters"):
if hasattr(tool, "filters") and tool.filters is not None:
parameters["filters"] = tool.filters.__dict__

if hasattr(tool, "max_num_results"):
if hasattr(tool, "max_num_results") and tool.max_num_results is not None:
parameters["max_num_results"] = tool.max_num_results

if hasattr(tool, "ranking_options"):
if hasattr(tool, "ranking_options") and tool.ranking_options is not None:
parameters["ranking_options"] = tool.ranking_options.__dict__

tool_data = tool.__dict__
Expand Down
74 changes: 74 additions & 0 deletions tests/unit/instrumentation/openai_core/test_response_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,80 @@ def test_get_response_tool_file_search_attributes(self):
assert "max_num_results" in result[MessageAttributes.TOOL_CALL_ARGUMENTS.format(i=0)]
assert "ranking_options" in result[MessageAttributes.TOOL_CALL_ARGUMENTS.format(i=0)]

def test_get_response_tool_web_search_attributes_with_none_user_location(self):
"""Test extraction of attributes from web search tool when user_location is None"""
# Create a mock web search tool with user_location=None (optional field default)
web_search_tool = MockWebSearchTool(
{"type": "web_search_preview", "search_context_size": "medium", "user_location": None}
)

# Call the function directly - should NOT raise AttributeError
with patch("agentops.instrumentation.providers.openai.attributes.response.WebSearchTool", MockWebSearchTool):
result = get_response_tool_web_search_attributes(web_search_tool, 0)

# Verify attributes - should still work without user_location
assert isinstance(result, dict)
assert MessageAttributes.TOOL_CALL_NAME.format(i=0) in result
assert result[MessageAttributes.TOOL_CALL_NAME.format(i=0)] == "web_search_preview"
assert MessageAttributes.TOOL_CALL_ARGUMENTS.format(i=0) in result
# user_location should NOT be in parameters since it was None
assert "user_location" not in result[MessageAttributes.TOOL_CALL_ARGUMENTS.format(i=0)]
# search_context_size should still be present
assert "search_context_size" in result[MessageAttributes.TOOL_CALL_ARGUMENTS.format(i=0)]

def test_get_response_tool_file_search_attributes_with_none_filters_and_ranking(self):
"""Test extraction of attributes from file search tool when filters and ranking_options are None"""
# Create a mock file search tool with filters=None and ranking_options=None (optional defaults)
file_search_tool = MockFileSearchTool(
{
"type": "file_search",
"vector_store_ids": ["store_123"],
"filters": None,
"max_num_results": 10,
"ranking_options": None,
}
)

# Call the function directly - should NOT raise AttributeError
with patch("agentops.instrumentation.providers.openai.attributes.response.FileSearchTool", MockFileSearchTool):
result = get_response_tool_file_search_attributes(file_search_tool, 0)

# Verify attributes - should still work without filters/ranking_options
assert isinstance(result, dict)
assert MessageAttributes.TOOL_CALL_TYPE.format(i=0) in result
assert result[MessageAttributes.TOOL_CALL_TYPE.format(i=0)] == "file_search"
assert MessageAttributes.TOOL_CALL_ARGUMENTS.format(i=0) in result
# filters and ranking_options should NOT be in parameters since they were None
assert "filters" not in result[MessageAttributes.TOOL_CALL_ARGUMENTS.format(i=0)]
assert "ranking_options" not in result[MessageAttributes.TOOL_CALL_ARGUMENTS.format(i=0)]
# vector_store_ids and max_num_results should still be present
assert "vector_store_ids" in result[MessageAttributes.TOOL_CALL_ARGUMENTS.format(i=0)]
assert "max_num_results" in result[MessageAttributes.TOOL_CALL_ARGUMENTS.format(i=0)]

def test_get_response_tool_search_attributes_skip_none_optional_parameters(self):
"""Test extraction skips optional search parameters when values are None"""
web_search_tool = MockWebSearchTool(
{"type": "web_search_preview", "search_context_size": None, "user_location": None}
)
file_search_tool = MockFileSearchTool(
{
"type": "file_search",
"vector_store_ids": None,
"filters": None,
"max_num_results": None,
"ranking_options": None,
}
)

with patch("agentops.instrumentation.providers.openai.attributes.response.WebSearchTool", MockWebSearchTool):
web_result = get_response_tool_web_search_attributes(web_search_tool, 0)

with patch("agentops.instrumentation.providers.openai.attributes.response.FileSearchTool", MockFileSearchTool):
file_result = get_response_tool_file_search_attributes(file_search_tool, 0)

assert MessageAttributes.TOOL_CALL_ARGUMENTS.format(i=0) not in web_result
assert MessageAttributes.TOOL_CALL_ARGUMENTS.format(i=0) not in file_result

def test_get_response_tool_computer_attributes(self):
"""Test extraction of attributes from computer tool"""
# Create a mock computer tool
Expand Down