ref(agno): Make agno use new integrations API - #132

Merged
Abhijeet Prasad (AbhiPrasad) merged 1 commit into
mainfrom
abhi-agno-migrate
Mar 24, 2026
Merged

ref(agno): Make agno use new integrations API#132
Abhijeet Prasad (AbhiPrasad) merged 1 commit into
mainfrom
abhi-agno-migrate

Conversation

@AbhiPrasad

@AbhiPrasadAbhijeet Prasad (AbhiPrasad) commented Mar 24, 2026

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stamp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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):

@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit 1163e11 into mainMar 24, 2026
33 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the abhi-agno-migrate branch March 24, 2026 23:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@AbhiPrasad@viadezo1er
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

ref(agno): Make agno use new integrations API - #132

Merged
Abhijeet Prasad (AbhiPrasad) merged 1 commit into
mainfrom
abhi-agno-migrate
Mar 24, 2026
Merged

ref(agno): Make agno use new integrations API#132
Abhijeet Prasad (AbhiPrasad) merged 1 commit into
mainfrom
abhi-agno-migrate

Conversation

@AbhiPrasad

@AbhiPrasadAbhijeet Prasad (AbhiPrasad) commented Mar 24, 2026

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stamp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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):

@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit 1163e11 into mainMar 24, 2026
33 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the abhi-agno-migrate branch March 24, 2026 23:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@AbhiPrasad@viadezo1er
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ref(agno): Make agno use new integrations API - #132

Merged
Abhijeet Prasad (AbhiPrasad) merged 1 commit into
mainfrom
abhi-agno-migrate
Mar 24, 2026
Merged

ref(agno): Make agno use new integrations API#132
Abhijeet Prasad (AbhiPrasad) merged 1 commit into
mainfrom
abhi-agno-migrate

Conversation

@AbhiPrasad

@AbhiPrasadAbhijeet Prasad (AbhiPrasad) commented Mar 24, 2026

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stamp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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):

@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit 1163e11 into mainMar 24, 2026
33 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the abhi-agno-migrate branch March 24, 2026 23:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@AbhiPrasad@viadezo1er
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ref(agno): Make agno use new integrations API - #132

Merged
Abhijeet Prasad (AbhiPrasad) merged 1 commit into
mainfrom
abhi-agno-migrate
Mar 24, 2026
Merged

ref(agno): Make agno use new integrations API#132
Abhijeet Prasad (AbhiPrasad) merged 1 commit into
mainfrom
abhi-agno-migrate

Conversation

@AbhiPrasad

@AbhiPrasadAbhijeet Prasad (AbhiPrasad) commented Mar 24, 2026

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stamp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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):

@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit 1163e11 into mainMar 24, 2026
33 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the abhi-agno-migrate branch March 24, 2026 23:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@AbhiPrasad@viadezo1er
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

ref(agno): Make agno use new integrations API - #132

Merged
Abhijeet Prasad (AbhiPrasad) merged 1 commit into
mainfrom
abhi-agno-migrate
Mar 24, 2026
Merged

ref(agno): Make agno use new integrations API#132
Abhijeet Prasad (AbhiPrasad) merged 1 commit into
mainfrom
abhi-agno-migrate

Conversation

@AbhiPrasad

@AbhiPrasadAbhijeet Prasad (AbhiPrasad) commented Mar 24, 2026

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stamp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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):

@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit 1163e11 into mainMar 24, 2026
33 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the abhi-agno-migrate branch March 24, 2026 23:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@AbhiPrasad@viadezo1er
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ref(agno): Make agno use new integrations API - #132

Merged
Abhijeet Prasad (AbhiPrasad) merged 1 commit into
mainfrom
abhi-agno-migrate
Mar 24, 2026
Merged

ref(agno): Make agno use new integrations API#132
Abhijeet Prasad (AbhiPrasad) merged 1 commit into
mainfrom
abhi-agno-migrate

Conversation

@AbhiPrasad

@AbhiPrasadAbhijeet Prasad (AbhiPrasad) commented Mar 24, 2026

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stamp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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):

@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit 1163e11 into mainMar 24, 2026
33 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the abhi-agno-migrate branch March 24, 2026 23:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@AbhiPrasad@viadezo1er
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ref(agno): Make agno use new integrations API - #132

Merged
Abhijeet Prasad (AbhiPrasad) merged 1 commit into
mainfrom
abhi-agno-migrate
Mar 24, 2026
Merged

ref(agno): Make agno use new integrations API#132
Abhijeet Prasad (AbhiPrasad) merged 1 commit into
mainfrom
abhi-agno-migrate

Conversation

@AbhiPrasad

@AbhiPrasadAbhijeet Prasad (AbhiPrasad) commented Mar 24, 2026

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stamp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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):

@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit 1163e11 into mainMar 24, 2026
33 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the abhi-agno-migrate branch March 24, 2026 23:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@AbhiPrasad@viadezo1er
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

ref(agno): Make agno use new integrations API - #132

Merged
Abhijeet Prasad (AbhiPrasad) merged 1 commit into
mainfrom
abhi-agno-migrate
Mar 24, 2026
Merged

ref(agno): Make agno use new integrations API#132
Abhijeet Prasad (AbhiPrasad) merged 1 commit into
mainfrom
abhi-agno-migrate

Conversation

@AbhiPrasad

@AbhiPrasadAbhijeet Prasad (AbhiPrasad) commented Mar 24, 2026

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stamp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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):

@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit 1163e11 into mainMar 24, 2026
33 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the abhi-agno-migrate branch March 24, 2026 23:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@AbhiPrasad@viadezo1er