diff --git a/py/src/braintrust/integrations/openai/test_openai.py b/py/src/braintrust/integrations/openai/test_openai.py index 439e4c02..7b1f502f 100644 --- a/py/src/braintrust/integrations/openai/test_openai.py +++ b/py/src/braintrust/integrations/openai/test_openai.py @@ -525,6 +525,10 @@ def test_openai_responses_web_search_tool_spans(memory_logger): tool_spans = _find_spans_by_type(spans, SpanTypeAttribute.TOOL) assert len(llm_spans) == 1 + if version_satisfies(openai.__version__, ">=3.41.0"): + tool_usage = response.tool_usage.model_dump(exclude_none=True) + assert tool_usage["web_search"]["num_requests"] == 1 + assert _try_to_dict(llm_spans[0]["metadata"]["tool_usage"]) == tool_usage tool_span = _find_span_by_name(tool_spans, "web_search_call") assert tool_span["span_parents"] == [llm_spans[0]["span_id"]] assert tool_span["metadata"]["tool_type"] == "web_search_call" @@ -566,6 +570,10 @@ def test_openai_responses_web_search_tool_spans_stream(memory_logger): tool_spans = _find_spans_by_type(spans, SpanTypeAttribute.TOOL) assert len(llm_spans) == 1 + if version_satisfies(openai.__version__, ">=3.41.0"): + tool_usage = final_response.tool_usage.model_dump(exclude_none=True) + assert tool_usage["web_search"]["num_requests"] == 1 + assert _try_to_dict(llm_spans[0]["metadata"]["tool_usage"]) == tool_usage tool_span = _find_span_by_name(tool_spans, "web_search_call") assert tool_span["span_parents"] == [llm_spans[0]["span_id"]] assert tool_span["metadata"]["tool_type"] == "web_search_call" diff --git a/py/src/braintrust/integrations/openai/tracing.py b/py/src/braintrust/integrations/openai/tracing.py index 38c83570..717f7e62 100644 --- a/py/src/braintrust/integrations/openai/tracing.py +++ b/py/src/braintrust/integrations/openai/tracing.py @@ -122,6 +122,7 @@ def start_span(*args, **kwargs): "object", "background", "incomplete_details", + "tool_usage", ) _EMBEDDING_METADATA_PARAMS = ( @@ -1735,6 +1736,10 @@ def _postprocess_streaming_results(cls, all_results: list[Any]) -> dict[str, Any for result in all_results: usage = getattr(result, "usage", None) + if getattr(result, "type", None) in ("response.completed", "response.incomplete", "response.failed"): + tool_usage = getattr(getattr(result, "response", None), "tool_usage", None) + if tool_usage is not None: + metadata["tool_usage"] = tool_usage if ( not usage and hasattr(result, "type")