refactor: Extract reusable function for building agent transfer instructions

Co-authored-by: Xiang (Sean) Zhou <seanzhougoogle@google.com>
PiperOrigin-RevId: 871410286
This commit is contained in:
Xiang (Sean) Zhou
2026-02-17 11:19:11 -08:00
committed by Copybara-Service
parent 4285f852d5
commit e1e0d63616
@@ -17,6 +17,7 @@
from __future__ import annotations
import typing
from typing import Any
from typing import AsyncGenerator
from typing_extensions import override
@@ -71,7 +72,8 @@ class _AgentTransferLlmRequestProcessor(BaseLlmRequestProcessor):
request_processor = _AgentTransferLlmRequestProcessor()
def _build_target_agents_info(target_agent: BaseAgent) -> str:
def _build_target_agents_info(target_agent: Any) -> str:
# TODO: Refactor the annotation of the parameters
return f"""
Agent name: {target_agent.name}
Agent description: {target_agent.description}
@@ -81,38 +83,30 @@ Agent description: {target_agent.description}
line_break = '\n'
def _build_transfer_instructions(
def _build_transfer_instruction_body(
tool_name: str,
agent: 'LlmAgent',
target_agents: list['BaseAgent'],
target_agents: list[Any],
) -> str:
"""Build instructions for agent transfer.
"""Build the core transfer instruction text.
TODO: Refactor the annotation of the parameters
This function generates the instruction text that guides the LLM on how to
use the transfer tool to delegate to other agents.
This is the agent-tree-agnostic portion of transfer instructions. It
works with any objects having ``.name`` and ``.description`` attributes
Args:
tool_name: The name of the transfer tool (e.g., 'transfer_to_agent').
agent: The current agent that may initiate transfers.
target_agents: List of agents that can be transferred to.
tool_name: The name of the transfer tool (e.g. 'transfer_to_agent').
target_agents: Objects with ``.name`` and ``.description``.
Returns:
Instruction text for the LLM about agent transfers.
"""
# Build list of available agent names for the NOTE
# target_agents already includes parent agent if applicable,
# so no need to add it again
available_agent_names = [target_agent.name for target_agent in target_agents]
# Sort for consistency
available_agent_names = [t.name for t in target_agents]
available_agent_names.sort()
# Format agent names with backticks for clarity
formatted_agent_names = ', '.join(
f'`{name}`' for name in available_agent_names
)
si = f"""
return f"""
You have a list of other agents to transfer to:
{line_break.join([
@@ -131,6 +125,27 @@ call.
{formatted_agent_names}.
"""
def _build_transfer_instructions(
tool_name: str,
agent: 'LlmAgent',
target_agents: list['BaseAgent'],
) -> str:
"""Build instructions for agent transfer (agent-tree variant).
Delegates to ``_build_transfer_instruction_body`` for the core text,
then appends parent-agent-specific instructions if applicable.
Args:
tool_name: The name of the transfer tool (e.g. 'transfer_to_agent').
agent: The current agent that may initiate transfers.
target_agents: List of agents that can be transferred to.
Returns:
Instruction text for the LLM about agent transfers.
"""
si = _build_transfer_instruction_body(tool_name, target_agents)
if agent.parent_agent and not agent.disallow_transfer_to_parent:
si += f"""
If neither you nor the other agents are best for the question, transfer to your parent agent {agent.parent_agent.name}.