How to pass user_id from root_agent to AgentTool

Currently I have an agent that receive user_id from adk Runner for calling custom tools for user data retrieval:

  1. Server init runner
runner = Runner(
    app_name=_APP_NAME,
    session_service=session_service,
    agent=expense_agent,
)
  1. Server calls runner, passing in the user_id
        async for event in runner.run_async(
            user_id=current_user_id,
            session_id=session_id,
            new_message=content
        ):
            if event.content and event.content.parts:
                for part in event.content.parts:
                    if part.text:
                        agent_responses.append({"type": "text", "content": part.text})
  1. In agent, define the tool
expense_agent = Agent(
    name="ExpenseManagementAgent",
    description=(
        "An agent that helps manage and retrieve user expenses."
        "This includes getting specific expense details, searching for expenses "
        "based on criteria (e.g., date, category, amount), or listing expenses."
        "Also helps in getting the currency rate for conversion purposes."
    ),
    model=settings.expense_agent_model,
    instruction=return_instructions_expense(),
    tools=[
        get_latest_n_expenses_tool,
    ]
)
  1. In the tool, get back the user_id from ToolContext
# --- ADK Tool Implementation ---
def get_latest_n_expenses_tool(
        tool_context: ToolContext,
        latest_n: int
        ) -> dict[str, Any]:
    """
    Fetches latest n expenses for the authenticated user.
    The user_id is retrieved from the tool_context.

    Args:
        tool_context: The ADK ToolContext, containing session and invocation info.
        latest_n: The number of expenses to fetch.

    Returns:
        A dictionary containing a list of expenses or an error message.
    """
    user_id = SessionUtil.get_user_id_for_tool(tool_context=tool_context)
    
    *** get data for user_id
  1. SessionUtil is a util func to get user_id from ToolContext
    def get_user_id_for_tool(tool_context: ToolContext) -> str:
        """
        Retrieve the user id from tool context for agent tools.
        """
        user_id = ""

        if (
            tool_context
            and tool_context._invocation_context
            and tool_context._invocation_context.session
        ):
            user_id = tool_context._invocation_context.session.user_id
            logger.info(f"In get_user_id_for_tool, user id: {user_id}")

        return user_id

Now I want to add CodeExecution tool and from the doc, I added a root agent as follows:

root_agent = Agent(
    name="RootAgent",
    model=settings.expense_agent_model,
    description="Root Agent",
    instruction=return_instructions_root(),
    tools=[
        agent_tool.AgentTool(agent=expense_agent),
        agent_tool.AgentTool(agent=code_agent)
    ],
)

However after that, I found that when root_agent calls the expense_agent, the expense agent is not able to retrieve the user_id from ToolContext. I also tried modify the tool’s argument to receive user_id as one of the param, ask the root agent to pass in the user_id. But still not able to pass the user_id from root to tool agent.

How can I do this? Thanks for the advice.

I had the same problem. When you use AgentTool, it creates a new session and a new user_id=“tmp_user” under the hood. The only data that is transferred is ‘state’. Therefore, you can specify the user_id in state and retrieve it from there.

1 Like

Hi ho.clarence,

You might find this page helpful in resolving your issue. It offers a suggested approach by diving into how ADK handles context propagation, especially in complex agent setups. The discussion explores practical strategies such as rewriting event sets and customizing content processors to maintain session continuity and manage token constraints effectively.

1 Like

Dear Nikita,

I used state and can access the user_id which was populated when creating session with state. Thanks a lot