diff --git a/core/src/agents/base_agent.ts b/core/src/agents/base_agent.ts index ce23dee..658cda9 100644 --- a/core/src/agents/base_agent.ts +++ b/core/src/agents/base_agent.ts @@ -89,8 +89,11 @@ export abstract class BaseAgent { /** * Root agent of this agent. + * Computed dynamically by traversing up the parent chain. */ - readonly rootAgent: BaseAgent; + get rootAgent(): BaseAgent { + return getRootAgent(this); + } /** * The parent agent of this agent. @@ -143,7 +146,6 @@ export abstract class BaseAgent { this.description = config.description; this.parentAgent = config.parentAgent; this.subAgents = config.subAgents || []; - this.rootAgent = getRootAgent(this); this.beforeAgentCallback = getCannonicalCallback( config.beforeAgentCallback, ); diff --git a/core/test/agents/base_agent_test.ts b/core/test/agents/base_agent_test.ts new file mode 100644 index 0000000..321a734 --- /dev/null +++ b/core/test/agents/base_agent_test.ts @@ -0,0 +1,43 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import {LlmAgent} from '@google/adk'; + +describe('BaseAgent', () => { + describe('rootAgent', () => { + it('should return the actual root agent for sub-agents', () => { + const subAgent = new LlmAgent({ + name: 'sub_agent', + description: 'A sub agent', + }); + + const rootAgent = new LlmAgent({ + name: 'root_agent', + description: 'The root agent', + subAgents: [subAgent], + }); + + expect(subAgent.rootAgent).toBe(rootAgent); + expect(rootAgent.rootAgent).toBe(rootAgent); + }); + + it('should traverse multiple levels of nesting', () => { + const leafAgent = new LlmAgent({name: 'leaf_agent'}); + const middleAgent = new LlmAgent({ + name: 'middle_agent', + subAgents: [leafAgent], + }); + const rootAgent = new LlmAgent({ + name: 'root_agent', + subAgents: [middleAgent], + }); + + expect(leafAgent.rootAgent).toBe(rootAgent); + expect(middleAgent.rootAgent).toBe(rootAgent); + expect(rootAgent.rootAgent).toBe(rootAgent); + }); + }); +});