ref(agno): Make agno use new integrations API#132
Merged
Abhijeet Prasad (AbhiPrasad) merged 1 commit intomainfrom Mar 24, 2026
Merged
ref(agno): Make agno use new integrations API#132Abhijeet Prasad (AbhiPrasad) merged 1 commit intomainfrom
Abhijeet Prasad (AbhiPrasad) merged 1 commit intomainfrom
Conversation
ViaDézo1er / cedric (viadezo1er)
approved these changes
Mar 24, 2026
Contributor
ViaDézo1er / cedric (viadezo1er)
left a comment
There was a problem hiding this comment.
stamp
Contributor
There was a problem hiding this comment.
Since there are many classes that are created and have the same attributes names, what about using a factory function?
diff --git a/py/src/braintrust/integrations/agno/patchers.py b/py/src/braintrust/integrations/agno/patchers.py
index 112c947..5228d49 100644
--- a/py/src/braintrust/integrations/agno/patchers.py
+++ b/py/src/braintrust/integrations/agno/patchers.py
@@ -1,4 +1,4 @@
-from typing import Any, ClassVar
+from typing import Any
from braintrust.integrations.base import CompositeFunctionWrapperPatcher, FunctionWrapperPatcher
@@ -34,66 +34,63 @@ from .tracing import (
)
+def _patcher(
+ name: str,
+ target_module: str,
+ target_path: str,
+ wrapper: Any,
+ *,
+ priority: int = 100,
+ superseded_by: tuple = (),
+) -> type[FunctionWrapperPatcher]:
+ """Create a FunctionWrapperPatcher subclass from plain data."""
+ attrs: dict[str, Any] = {
+ "name": name,
+ "target_module": target_module,
+ "target_path": target_path,
+ "wrapper": wrapper,
+ }
+ if priority != 100:
+ attrs["priority"] = priority
+ if superseded_by:
+ attrs["superseded_by"] = superseded_by
+ return type(f"_{name}", (FunctionWrapperPatcher,), attrs) # type: ignore[return-value]
+
+
# ---------------------------------------------------------------------------
# Agent patchers
# ---------------------------------------------------------------------------
# Private methods have higher priority (lower number) so they are tried first.
-# The public fallback patchers override applies() to yield when the private
+# The public fallback patchers use superseded_by to yield when the private
# variant exists.
-
-class _AgentRunPrivatePatcher(FunctionWrapperPatcher):
- name = "agno.agent.run.private"
- target_module = "agno.agent"
- target_path = "Agent._run"
- wrapper = _agent_run_private_wrapper
- priority: ClassVar[int] = 50
-
-
-class _AgentRunPublicPatcher(FunctionWrapperPatcher):
- """Fallback: wrap ``Agent.run`` only when ``Agent._run`` does not exist."""
-
- name = "agno.agent.run.public"
- target_module = "agno.agent"
- target_path = "Agent.run"
- wrapper = _agent_run_public_wrapper
- priority: ClassVar[int] = 100
- superseded_by = (_AgentRunPrivatePatcher,)
-
-
-class _AgentArunPrivatePatcher(FunctionWrapperPatcher):
- name = "agno.agent.arun.private"
- target_module = "agno.agent"
- target_path = "Agent._arun"
- wrapper = _agent_arun_private_wrapper
- priority: ClassVar[int] = 50
-
-
-class _AgentRunStreamPatcher(FunctionWrapperPatcher):
- name = "agno.agent.run_stream"
- target_module = "agno.agent"
- target_path = "Agent._run_stream"
- wrapper = _agent_run_stream_wrapper
-
-
-class _AgentArunStreamPatcher(FunctionWrapperPatcher):
- name = "agno.agent.arun_stream"
- target_module = "agno.agent"
- target_path = "Agent._arun_stream"
- wrapper = _agent_arun_stream_wrapper
- priority: ClassVar[int] = 50
-
-
-class _AgentArunPublicPatcher(FunctionWrapperPatcher):
- """Fallback: wrap ``Agent.arun`` only when neither ``_arun`` nor ``_arun_stream`` exist."""
-
- name = "agno.agent.arun.public"
- target_module = "agno.agent"
- target_path = "Agent.arun"
- wrapper = _agent_arun_public_wrapper
- priority: ClassVar[int] = 100
- superseded_by = (_AgentArunPrivatePatcher, _AgentArunStreamPatcher)
+_AgentRunPrivatePatcher = _patcher(
+ "agno.agent.run.private", "agno.agent", "Agent._run", _agent_run_private_wrapper, priority=50
+)
+_AgentRunPublicPatcher = _patcher(
+ "agno.agent.run.public",
+ "agno.agent",
+ "Agent.run",
+ _agent_run_public_wrapper,
+ superseded_by=(_AgentRunPrivatePatcher,),
+)
+_AgentArunPrivatePatcher = _patcher(
+ "agno.agent.arun.private", "agno.agent", "Agent._arun", _agent_arun_private_wrapper, priority=50
+)
+_AgentRunStreamPatcher = _patcher(
+ "agno.agent.run_stream", "agno.agent", "Agent._run_stream", _agent_run_stream_wrapper
+)
+_AgentArunStreamPatcher = _patcher(
+ "agno.agent.arun_stream", "agno.agent", "Agent._arun_stream", _agent_arun_stream_wrapper, priority=50
+)
+_AgentArunPublicPatcher = _patcher(
+ "agno.agent.arun.public",
+ "agno.agent",
+ "Agent.arun",
+ _agent_arun_public_wrapper,
+ superseded_by=(_AgentArunPrivatePatcher, _AgentArunStreamPatcher),
+)
class AgentPatcher(CompositeFunctionWrapperPatcher):
@@ -114,58 +111,26 @@ class AgentPatcher(CompositeFunctionWrapperPatcher):
# Team patchers
# ---------------------------------------------------------------------------
-
-class _TeamRunPrivatePatcher(FunctionWrapperPatcher):
- name = "agno.team.run.private"
- target_module = "agno.team"
- target_path = "Team._run"
- wrapper = _team_run_private_wrapper
- priority: ClassVar[int] = 50
-
-
-class _TeamRunPublicPatcher(FunctionWrapperPatcher):
- """Fallback: wrap ``Team.run`` only when ``Team._run`` does not exist."""
-
- name = "agno.team.run.public"
- target_module = "agno.team"
- target_path = "Team.run"
- wrapper = _team_run_public_wrapper
- priority: ClassVar[int] = 100
- superseded_by = (_TeamRunPrivatePatcher,)
-
-
-class _TeamArunPrivatePatcher(FunctionWrapperPatcher):
- name = "agno.team.arun.private"
- target_module = "agno.team"
- target_path = "Team._arun"
- wrapper = _team_arun_private_wrapper
- priority: ClassVar[int] = 50
-
-
-class _TeamRunStreamPatcher(FunctionWrapperPatcher):
- name = "agno.team.run_stream"
- target_module = "agno.team"
- target_path = "Team._run_stream"
- wrapper = _team_run_stream_wrapper
-
-
-class _TeamArunStreamPatcher(FunctionWrapperPatcher):
- name = "agno.team.arun_stream"
- target_module = "agno.team"
- target_path = "Team._arun_stream"
- wrapper = _team_arun_stream_wrapper
- priority: ClassVar[int] = 50
-
-
-class _TeamArunPublicPatcher(FunctionWrapperPatcher):
- """Fallback: wrap ``Team.arun`` only when neither ``_arun`` nor ``_arun_stream`` exist."""
-
- name = "agno.team.arun.public"
- target_module = "agno.team"
- target_path = "Team.arun"
- wrapper = _team_arun_public_wrapper
- priority: ClassVar[int] = 100
- superseded_by = (_TeamArunPrivatePatcher, _TeamArunStreamPatcher)
+_TeamRunPrivatePatcher = _patcher(
+ "agno.team.run.private", "agno.team", "Team._run", _team_run_private_wrapper, priority=50
+)
+_TeamRunPublicPatcher = _patcher(
+ "agno.team.run.public", "agno.team", "Team.run", _team_run_public_wrapper, superseded_by=(_TeamRunPrivatePatcher,)
+)
+_TeamArunPrivatePatcher = _patcher(
+ "agno.team.arun.private", "agno.team", "Team._arun", _team_arun_private_wrapper, priority=50
+)
+_TeamRunStreamPatcher = _patcher("agno.team.run_stream", "agno.team", "Team._run_stream", _team_run_stream_wrapper)
+_TeamArunStreamPatcher = _patcher(
+ "agno.team.arun_stream", "agno.team", "Team._arun_stream", _team_arun_stream_wrapper, priority=50
+)
+_TeamArunPublicPatcher = _patcher(
+ "agno.team.arun.public",
+ "agno.team",
+ "Team.arun",
+ _team_arun_public_wrapper,
+ superseded_by=(_TeamArunPrivatePatcher, _TeamArunStreamPatcher),
+)
class TeamPatcher(CompositeFunctionWrapperPatcher):
@@ -186,61 +151,24 @@ class TeamPatcher(CompositeFunctionWrapperPatcher):
# Model patchers
# ---------------------------------------------------------------------------
-
-class _ModelInvokePatcher(FunctionWrapperPatcher):
- name = "agno.model.invoke"
- target_module = "agno.models.base"
- target_path = "Model.invoke"
- wrapper = _model_invoke_wrapper
-
-
-class _ModelAinvokePatcher(FunctionWrapperPatcher):
- name = "agno.model.ainvoke"
- target_module = "agno.models.base"
- target_path = "Model.ainvoke"
- wrapper = _model_ainvoke_wrapper
-
-
-class _ModelInvokeStreamPatcher(FunctionWrapperPatcher):
- name = "agno.model.invoke_stream"
- target_module = "agno.models.base"
- target_path = "Model.invoke_stream"
- wrapper = _model_invoke_stream_wrapper
-
-
-class _ModelAinvokeStreamPatcher(FunctionWrapperPatcher):
- name = "agno.model.ainvoke_stream"
- target_module = "agno.models.base"
- target_path = "Model.ainvoke_stream"
- wrapper = _model_ainvoke_stream_wrapper
-
-
-class _ModelResponsePatcher(FunctionWrapperPatcher):
- name = "agno.model.response"
- target_module = "agno.models.base"
- target_path = "Model.response"
- wrapper = _model_response_wrapper
-
-
-class _ModelAresponsePatcher(FunctionWrapperPatcher):
- name = "agno.model.aresponse"
- target_module = "agno.models.base"
- target_path = "Model.aresponse"
- wrapper = _model_aresponse_wrapper
-
-
-class _ModelResponseStreamPatcher(FunctionWrapperPatcher):
- name = "agno.model.response_stream"
- target_module = "agno.models.base"
- target_path = "Model.response_stream"
- wrapper = _model_response_stream_wrapper
-
-
-class _ModelAresponseStreamPatcher(FunctionWrapperPatcher):
- name = "agno.model.aresponse_stream"
- target_module = "agno.models.base"
- target_path = "Model.aresponse_stream"
- wrapper = _model_aresponse_stream_wrapper
+_ModelInvokePatcher = _patcher("agno.model.invoke", "agno.models.base", "Model.invoke", _model_invoke_wrapper)
+_ModelAinvokePatcher = _patcher("agno.model.ainvoke", "agno.models.base", "Model.ainvoke", _model_ainvoke_wrapper)
+_ModelInvokeStreamPatcher = _patcher(
+ "agno.model.invoke_stream", "agno.models.base", "Model.invoke_stream", _model_invoke_stream_wrapper
+)
+_ModelAinvokeStreamPatcher = _patcher(
+ "agno.model.ainvoke_stream", "agno.models.base", "Model.ainvoke_stream", _model_ainvoke_stream_wrapper
+)
+_ModelResponsePatcher = _patcher("agno.model.response", "agno.models.base", "Model.response", _model_response_wrapper)
+_ModelAresponsePatcher = _patcher(
+ "agno.model.aresponse", "agno.models.base", "Model.aresponse", _model_aresponse_wrapper
+)
+_ModelResponseStreamPatcher = _patcher(
+ "agno.model.response_stream", "agno.models.base", "Model.response_stream", _model_response_stream_wrapper
+)
+_ModelAresponseStreamPatcher = _patcher(
+ "agno.model.aresponse_stream", "agno.models.base", "Model.aresponse_stream", _model_aresponse_stream_wrapper
+)
class ModelPatcher(CompositeFunctionWrapperPatcher):
@@ -263,19 +191,12 @@ class ModelPatcher(CompositeFunctionWrapperPatcher):
# FunctionCall patchers
# ---------------------------------------------------------------------------
-
-class _FunctionCallExecutePatcher(FunctionWrapperPatcher):
- name = "agno.function_call.execute"
- target_module = "agno.tools.function"
- target_path = "FunctionCall.execute"
- wrapper = _function_call_execute_wrapper
-
-
-class _FunctionCallAexecutePatcher(FunctionWrapperPatcher):
- name = "agno.function_call.aexecute"
- target_module = "agno.tools.function"
- target_path = "FunctionCall.aexecute"
- wrapper = _function_call_aexecute_wrapper
+_FunctionCallExecutePatcher = _patcher(
+ "agno.function_call.execute", "agno.tools.function", "FunctionCall.execute", _function_call_execute_wrapper
+)
+_FunctionCallAexecutePatcher = _patcher(
+ "agno.function_call.aexecute", "agno.tools.function", "FunctionCall.aexecute", _function_call_aexecute_wrapper
+)
class FunctionCallPatcher(CompositeFunctionWrapperPatcher):
@@ -292,47 +213,30 @@ class FunctionCallPatcher(CompositeFunctionWrapperPatcher):
# Workflow patchers (optional — requires fastapi)
# ---------------------------------------------------------------------------
-
-class _WorkflowExecutePatcher(FunctionWrapperPatcher):
- name = "agno.workflow.execute"
- target_module = "agno.workflow"
- target_path = "Workflow._execute"
- wrapper = _workflow_execute_wrapper
-
-
-class _WorkflowExecuteStreamPatcher(FunctionWrapperPatcher):
- name = "agno.workflow.execute_stream"
- target_module = "agno.workflow"
- target_path = "Workflow._execute_stream"
- wrapper = _workflow_execute_stream_wrapper
-
-
-class _WorkflowAexecutePatcher(FunctionWrapperPatcher):
- name = "agno.workflow.aexecute"
- target_module = "agno.workflow"
- target_path = "Workflow._aexecute"
- wrapper = _workflow_aexecute_wrapper
-
-
-class _WorkflowAexecuteStreamPatcher(FunctionWrapperPatcher):
- name = "agno.workflow.aexecute_stream"
- target_module = "agno.workflow"
- target_path = "Workflow._aexecute_stream"
- wrapper = _workflow_aexecute_stream_wrapper
-
-
-class _WorkflowExecuteWorkflowAgentPatcher(FunctionWrapperPatcher):
- name = "agno.workflow.execute_workflow_agent"
- target_module = "agno.workflow"
- target_path = "Workflow._execute_workflow_agent"
- wrapper = _workflow_execute_workflow_agent_wrapper
-
-
-class _WorkflowAexecuteWorkflowAgentPatcher(FunctionWrapperPatcher):
- name = "agno.workflow.aexecute_workflow_agent"
- target_module = "agno.workflow"
- target_path = "Workflow._aexecute_workflow_agent"
- wrapper = _workflow_aexecute_workflow_agent_wrapper
+_WorkflowExecutePatcher = _patcher(
+ "agno.workflow.execute", "agno.workflow", "Workflow._execute", _workflow_execute_wrapper
+)
+_WorkflowExecuteStreamPatcher = _patcher(
+ "agno.workflow.execute_stream", "agno.workflow", "Workflow._execute_stream", _workflow_execute_stream_wrapper
+)
+_WorkflowAexecutePatcher = _patcher(
+ "agno.workflow.aexecute", "agno.workflow", "Workflow._aexecute", _workflow_aexecute_wrapper
+)
+_WorkflowAexecuteStreamPatcher = _patcher(
+ "agno.workflow.aexecute_stream", "agno.workflow", "Workflow._aexecute_stream", _workflow_aexecute_stream_wrapper
+)
+_WorkflowExecuteWorkflowAgentPatcher = _patcher(
+ "agno.workflow.execute_workflow_agent",
+ "agno.workflow",
+ "Workflow._execute_workflow_agent",
+ _workflow_execute_workflow_agent_wrapper,
+)
+_WorkflowAexecuteWorkflowAgentPatcher = _patcher(
+ "agno.workflow.aexecute_workflow_agent",
+ "agno.workflow",
+ "Workflow._aexecute_workflow_agent",
+ _workflow_aexecute_workflow_agent_wrapper,
+)
class WorkflowPatcher(CompositeFunctionWrapperPatcher):
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ref #116
Convert the Agno instrumentation from the legacy wrappers pattern to the new integrations API introduced in #118.
I also heavily edited the agent skills with some of the learnings I made while doing this. Should become much more effective now.