-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Description
Describe the Bug:
Plugin callbacks (before_agent, after_agent, before_model, after_model, on_user_message, before_run, after_run) are not being invoked by InMemoryRunner, despite being registered and the documentation stating they should be global and have precedence over agent callbacks. Only tool callbacks fire when passed directly to the agent.
Steps to Reproduce:
- Create a plugin extending BasePlugin with callback methods (before_agent, before_model, etc.)
- Register the plugin with InMemoryRunner(agent=root_agent, plugins=[MyPlugin()])
- Run the agent using adk run or runner.run_async()
- Observe that only tool callbacks fire, while agent and model callbacks never execute
Expected Behavior:
According to ADK documentation, plugin callbacks should be invoked automatically by the runner at various lifecycle points:
on_user_message_callback - when user sends a message
before_run_callback / after_run_callback - when runner starts/completes
before_agent_callback / after_agent_callback - when agent executes
before_model_callback / after_model_callback - when LLM is called
before_tool_callback / after_tool_callback - when tool executes
Observed Behavior: Only before_tool_callback and after_tool_callback fire (when passed directly to the agent). All other plugin callbacks registered on the runner never fire. The plugin initializes successfully but its lifecycle callbacks are never invoked.
Environment Details:
ADK Library Version (pip show google-adk): 1.25.0
Desktop OS: Linux
Python Version: 3.11/3.12
Model Information: Using Bedrock model via LiteLLM
Logs:
✅ [PLUGIN] Auditor plugin initialized
🛠️ [AUDIT] Before tool callback fired for consult_receptionist!
✅ [AUDIT] After tool callback fired for consult_receptionist!
Note: Agent and model callbacks never appear in logs despite being implemented.
Minimal Reproduction Code:
from google.adk.plugins.base_plugin import BasePlugin
from google.adk.agents.callback_context import CallbackContext
from google.adk.runners import InMemoryRunner
from google.adk.agents import LlmAgent
class AuditorPlugin(BasePlugin):
def __init__(self):
super().__init__(name="auditor_plugin")
print("✅ [PLUGIN] Auditor plugin initialized")
async def before_agent_callback(self, *, agent, callback_context: CallbackContext) -> None:
print(f"🤖 [AUDIT] Before agent callback fired for {agent.name}!")
async def after_agent_callback(self, *, agent, callback_context: CallbackContext) -> None:
print(f"✅ [AUDIT] After agent callback fired for {agent.name}!")
async def before_model_callback(self, *, callback_context: CallbackContext, llm_request) -> None:
print("🧠 [AUDIT] Before model callback fired!")
async def after_model_callback(self, *, callback_context: CallbackContext, llm_request) -> None:
print("✅ [AUDIT] After model callback fired!")
root_agent = LlmAgent(
name="test_agent",
model="gemini-2.0-flash",
instruction="Test agent",
tools=[],
)
runner = InMemoryRunner(
agent=root_agent,
plugins=[AuditorPlugin()],
)
Run the agent - observe that only plugin init prints, but agent/model callbacks never fire
How often has this issue occurred?:
Always (100%)