diff --git a/sentry_sdk/integrations/openai_agents/spans/ai_client.py b/sentry_sdk/integrations/openai_agents/spans/ai_client.py index 697f0d6cf7..29b5c8cd26 100644 --- a/sentry_sdk/integrations/openai_agents/spans/ai_client.py +++ b/sentry_sdk/integrations/openai_agents/spans/ai_client.py @@ -46,6 +46,7 @@ from ..consts import SPAN_ORIGIN from ..utils import ( + _get_request_model_name, _set_agent_data, _set_input_data, _set_output_data, @@ -201,11 +202,7 @@ def ai_client_span( agent: "Agent", get_response_kwargs: "dict[str, Any]" ) -> "Union[sentry_sdk.tracing.Span, StreamedSpan]": # TODO-anton: implement other types of operations. Now "chat" is hardcoded. - model_name = None - if agent.model: - model_name = agent.model.model if hasattr(agent.model, "model") else agent.model - elif hasattr(agent, "_sentry_request_model"): - model_name = agent._sentry_request_model + model_name = _get_request_model_name(agent) client_options = sentry_sdk.get_client().options diff --git a/sentry_sdk/integrations/openai_agents/utils.py b/sentry_sdk/integrations/openai_agents/utils.py index 01303e0e58..53a6b14404 100644 --- a/sentry_sdk/integrations/openai_agents/utils.py +++ b/sentry_sdk/integrations/openai_agents/utils.py @@ -48,6 +48,23 @@ def _capture_exception(exc: "Any") -> None: sentry_sdk.capture_event(event, hint=hint) +def _get_request_model_name(agent: "agents.Agent") -> "Optional[str]": + """Resolve the request model name used on openai-agents spans. + + Precedence matches the previous duplicated lookups: + 1. ``agent.model.model`` when ``agent.model`` is a ``Model`` instance + 2. ``agent.model`` when it is a string + 3. ``agent._sentry_request_model`` when the agent uses a default model + """ + if isinstance(agent.model, Model) and hasattr(agent.model, "model"): + return agent.model.model + if isinstance(agent.model, str): + return agent.model + if hasattr(agent, "_sentry_request_model"): + return agent._sentry_request_model + return None + + def _set_agent_data( span: "Union[sentry_sdk.tracing.Span, StreamedSpan]", agent: "agents.Agent" ) -> None: @@ -64,14 +81,7 @@ def _set_agent_data( if agent.model_settings.max_tokens: set_on_span(SPANDATA.GEN_AI_REQUEST_MAX_TOKENS, agent.model_settings.max_tokens) - model_name: "Optional[str]" = None - if isinstance(agent.model, Model) and hasattr(agent.model, "model"): - model_name = agent.model.model - elif isinstance(agent.model, str): - model_name = agent.model - elif hasattr(agent, "_sentry_request_model"): - model_name = agent._sentry_request_model - + model_name = _get_request_model_name(agent) if model_name: set_on_span(SPANDATA.GEN_AI_REQUEST_MODEL, model_name) diff --git a/tests/integrations/openai_agents/test_request_model.py b/tests/integrations/openai_agents/test_request_model.py new file mode 100644 index 0000000000..32092fc249 --- /dev/null +++ b/tests/integrations/openai_agents/test_request_model.py @@ -0,0 +1,34 @@ +from agents import Agent +from agents.models.openai_responses import OpenAIResponsesModel +from openai import AsyncOpenAI + +from sentry_sdk.integrations.openai_agents.utils import _get_request_model_name + + +def test_request_model_name_prefers_model_instance_over_sentry_fallback(): + client = AsyncOpenAI(api_key="test-key") + model = OpenAIResponsesModel(model="gpt-4", openai_client=client) + agent = Agent(name="test_agent", model=model) + agent._sentry_request_model = "fallback-model" + + assert _get_request_model_name(agent) == "gpt-4" + + +def test_request_model_name_prefers_string_model_over_sentry_fallback(): + agent = Agent(name="test_agent", model="gpt-4o-mini") + agent._sentry_request_model = "fallback-model" + + assert _get_request_model_name(agent) == "gpt-4o-mini" + + +def test_request_model_name_falls_back_to_sentry_request_model(): + agent = Agent(name="test_agent", model=None) + agent._sentry_request_model = "default-from-run-config" + + assert _get_request_model_name(agent) == "default-from-run-config" + + +def test_request_model_name_returns_none_without_model_or_fallback(): + agent = Agent(name="test_agent", model=None) + + assert _get_request_model_name(agent) is None