Skip to content

Support list of callbacks for agent lifecycle hooks (before_agent_callback, after_agent_callback, etc.) #5583

@kaligautier

Description

@kaligautier

Feature Request

Problem

In the Python SDK, agent lifecycle callback parameters (before_agent_callback, after_agent_callback, before_model_callback, etc.) accept only a single callable. When multiple concerns need to run at the same hook point (e.g., logging + data injection before an agent starts), developers are forced to write a manual composite wrapper:

async def before_portfolio_analyzer(callback_context: CallbackContext) -> None:
    log_agent_start(callback_context)
    await inject_portfolio_data(callback_context)

portfolio_analyzer = LlmAgent(
    before_agent_callback=before_portfolio_analyzer,  # manual composition
)

This adds boilerplate and breaks the "1 callback = 1 responsibility" principle.

Existing precedent in Go SDK

The Go SDK already supports lists of callbacks:

llmCfg := llmagent.Config{
    BeforeAgentCallbacks: []agent.BeforeAgentCallback{onBeforeAgent},
    AfterAgentCallbacks:  []agent.AfterAgentCallback{onAfterAgent},
    BeforeModelCallbacks: []llmagent.BeforeModelCallback{onBeforeModel},
    BeforeToolCallbacks:  []llmagent.BeforeToolCallback{onBeforeTool},
}

Proposed solution

Accept either a single callable or a list of callables for all callback parameters in Python:

portfolio_analyzer = LlmAgent(
    before_agent_callback=[log_agent_start, inject_portfolio_data],
    before_model_callback=log_before_model,  # single callable still works
)

Callbacks in the list would execute sequentially. If any callback returns a non-None value (e.g., Content to skip the agent), subsequent callbacks in the list should be skipped (short-circuit).

Benefits

  • Parity with Go SDK — consistent behavior across SDKs
  • Composability — mix and match reusable callback functions without manual wrappers
  • Single Responsibility — each callback function stays focused on one concern

Environment

  • Python SDK
  • Affects: BaseAgent (before_agent_callback, after_agent_callback) and LlmAgent (before_model_callback, after_model_callback, before_tool_callback, after_tool_callback)

Metadata

Metadata

Labels

core[Component] This issue is related to the core interface and implementationneeds review[Status] The PR/issue is awaiting review from the maintainer

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions