Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,29 @@ def export(self):

@pytest.mark.asyncio
@pytest.mark.vcr
async def test_openai_agents_integration_setup_creates_spans(memory_logger):
async def test_openai_agents_integration_setup_creates_spans(memory_logger, monkeypatch):
import agents
from agents import Agent
from agents.run import AgentRunner
from braintrust.integrations.openai_agents import tracing

assert not memory_logger.pop()

assert OpenAIAgentsIntegration.setup() is True
assert agents.tracing.get_trace_provider()._disabled is False

response_metadata = []
response_log_data = tracing.BraintrustTracingProcessor._response_log_data

def capture_response_metadata(self, span):
response = span.span_data.response
if response is not None:
response.metadata["user"] = "preserve-me"
response_metadata.append((response.metadata, dict(response.metadata or {})))
return response_log_data(self, span)

monkeypatch.setattr(tracing.BraintrustTracingProcessor, "_response_log_data", capture_response_metadata)

agent = Agent(name="test-agent", model=TEST_MODEL, instructions=TEST_AGENT_INSTRUCTIONS)
result = await AgentRunner().run(agent, TEST_PROMPT)

Expand Down Expand Up @@ -116,6 +129,15 @@ async def test_openai_agents_integration_setup_creates_spans(memory_logger):
assert any(metrics.get("prompt_cached_tokens") == 0 for metrics in llm_metrics)
assert any(metrics.get("completion_reasoning_tokens") == 0 for metrics in llm_metrics)

assert response_metadata
for metadata, original_metadata in response_metadata:
assert metadata == original_metadata

response_spans = [span for span in llm_spans if span.get("span_attributes", {}).get("name") == "Response"]
assert response_spans
assert any(span.get("metadata", {}).get("user") == "preserve-me" for span in response_spans)
assert all(value is not None for span in response_spans for value in span.get("metadata", {}).values())

# v0.14.0+ produces TaskSpanData and TurnSpanData wrapping agent runs. The
# tracing processor must give them proper names, metadata, and usage
# metrics rather than returning "Unknown" / empty dicts.
Expand Down
4 changes: 2 additions & 2 deletions py/src/braintrust/integrations/openai_agents/tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@ def _response_log_data(self, span: tracing.Span[tracing.ResponseSpanData]) -> di
if span.span_data.response is not None:
data["output"] = span.span_data.response.output
if span.span_data.response is not None:
data["metadata"] = span.span_data.response.metadata or {}
data["metadata"] = dict(span.span_data.response.metadata or {})
data["metadata"].update(
span.span_data.response.model_dump(exclude={"input", "output", "metadata", "usage"})
span.span_data.response.model_dump(exclude={"input", "output", "metadata", "usage"}, exclude_none=True)
)

data["metrics"] = {}
Expand Down
Loading