Skip to content

LlmAgent.clone() keeps the original's sub-agent tools and finish_task #7894

Closed

Description

@hyeonsang010716

🔴 Required Information

Describe the Bug:
LlmAgent.model_post_init adds a tool for each single_turn or task sub-agent (_SingleTurnAgentTool / _TaskAgentTool), and FinishTaskTool when the agent itself is in task mode. LlmAgent.clone() goes through BaseAgent.clone(), which uses model_copy. model_copy does not run model_post_init again, and tools is only shallow-copied, so the clone keeps the original's tool objects:

  • The clone's sub-agent tools still wrap the original's sub-agents, not the clone's. A single_turn call from the clone runs the original sub-agent, so changes made to the clone's sub-agents are ignored.
  • clone(update={"sub_agents": [...]}) does not add tools for the new sub-agents, and keeps the tools for the old ones. The model cannot call the new sub-agents. Calling an old one runs an agent that is no longer in the tree (single_turn), or fails with WorkflowConfigurationError: Task target agent '...' not found. (task).
  • clone(update={"tools": [...]}) drops the sub-agent tools, so those sub-agents cannot be called at all.
  • clone(update={"mode": ...}) or clone(update={"output_schema": ...}) leaves finish_task as it was on the original.

Steps to Reproduce:

  1. Run the code below.

Expected Behavior:
A clone has the same tools it would get if it were constructed with its own fields: one tool per single_turn / task sub-agent of the clone, and finish_task matching the clone's mode and output schema.

True
False
['other'] ['other']
['helper']

Observed Behavior:

False
True
['other'] ['helper']
[]

Environment Details:

  • ADK Library Version (pip show google-adk): 2.13.0 (also on main at e9e8f61)
  • Desktop OS: macOS
  • Python Version (python -V): 3.14.7

Model Information:

  • Are you using LiteLLM: No
  • Which model is being used: N/A (no model call is needed to reproduce)

🟡 Optional Information

Additional Context:
Running a clone through InMemoryRunner with a mocked model shows the same thing. When the clone's single_turn sub-agent has a changed instruction, the sub-agent's model still receives the original instruction.

task delegation itself looks up the target with root_agent.find_agent(fc.name) in _dispatch_task_fc, so a plain clone() of a task sub-agent still reaches the clone's sub-agent. The update cases above are where task breaks.

Minimal Reproduction Code:

from google.adk.agents import LlmAgent

helper = LlmAgent(name="helper", description="Helps", mode="single_turn")
root = LlmAgent(name="root", sub_agents=[helper])

clone = root.clone()
print(clone.tools[0].agent is clone.sub_agents[0])
print(clone.tools[0].agent is helper)

other = LlmAgent(name="other", description="Other", mode="single_turn")
clone = root.clone(update={"sub_agents": [other]})
print([a.name for a in clone.sub_agents], [t.name for t in clone.tools])

clone = root.clone(update={"tools": []})
print([t.name for t in clone.tools])

How often has this issue occurred?:

  • Always (100%)

Activity

  1. added theissue type on Nov 5, 2026
  2. added
    core[Component] This issue is related to the core interface and implementation
    on Nov 5, 2026
  3. llalitkumarrr commented on Nov 5, 2026

    @llalitkumarrr
    Collaborator

    Hello @hyeonsang010716,

    Thank you for raising this issue and for your contribution. We were able to reproduce the problem and have tested your PR which should resolve it. However the PR is still under review and can only be merged once the reviewers approve the changes. In the meantime we appreciate your patience. We will reach out if we need further information.

  4. added a commit that references this issue on Nov 9, 2026
    b41fc57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

core[Component] This issue is related to the core interface and implementation

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions