diff --git a/src/google/adk/auth/auth_preprocessor.py b/src/google/adk/auth/auth_preprocessor.py index fc50cdff..37ad6745 100644 --- a/src/google/adk/auth/auth_preprocessor.py +++ b/src/google/adk/auth/auth_preprocessor.py @@ -15,7 +15,6 @@ from __future__ import annotations from typing import AsyncGenerator -from typing import TYPE_CHECKING from typing_extensions import override @@ -30,9 +29,6 @@ from .auth_handler import AuthHandler from .auth_tool import AuthConfig from .auth_tool import AuthToolArguments -if TYPE_CHECKING: - from ..agents.llm_agent import LlmAgent - # Prefix used by toolset auth credential IDs. # Auth requests with this prefix are for toolset authentication (before tool # listing) and don't require resuming a function call. @@ -46,10 +42,8 @@ class _AuthLlmRequestProcessor(BaseLlmRequestProcessor): async def run_async( self, invocation_context: InvocationContext, llm_request: LlmRequest ) -> AsyncGenerator[Event, None]: - from ..agents.llm_agent import LlmAgent - agent = invocation_context.agent - if not isinstance(agent, LlmAgent): + if not hasattr(agent, 'canonical_tools'): return events = invocation_context.session.events if not events: diff --git a/src/google/adk/flows/llm_flows/_code_execution.py b/src/google/adk/flows/llm_flows/_code_execution.py index a6f9f3be..8c3edfc9 100644 --- a/src/google/adk/flows/llm_flows/_code_execution.py +++ b/src/google/adk/flows/llm_flows/_code_execution.py @@ -120,9 +120,7 @@ class _CodeExecutionRequestProcessor(BaseLlmRequestProcessor): async def run_async( self, invocation_context: InvocationContext, llm_request: LlmRequest ) -> AsyncGenerator[Event, None]: - from ...agents.llm_agent import LlmAgent - - if not isinstance(invocation_context.agent, LlmAgent): + if not hasattr(invocation_context.agent, 'code_executor'): return if not invocation_context.agent.code_executor: return @@ -175,9 +173,7 @@ async def _run_pre_processor( llm_request: LlmRequest, ) -> AsyncGenerator[Event, None]: """Pre-process the user message by adding the user message to the Colab notebook.""" - from ...agents.llm_agent import LlmAgent - - if not isinstance(invocation_context.agent, LlmAgent): + if not hasattr(invocation_context.agent, 'code_executor'): return agent = invocation_context.agent diff --git a/src/google/adk/flows/llm_flows/_nl_planning.py b/src/google/adk/flows/llm_flows/_nl_planning.py index e66da5a4..760786a1 100644 --- a/src/google/adk/flows/llm_flows/_nl_planning.py +++ b/src/google/adk/flows/llm_flows/_nl_planning.py @@ -109,11 +109,10 @@ response_processor = _NlPlanningResponse() def _get_planner( invocation_context: InvocationContext, ) -> Optional[BasePlanner]: - from ...agents.llm_agent import Agent from ...planners.base_planner import BasePlanner agent = invocation_context.agent - if not isinstance(agent, Agent): + if not hasattr(agent, 'planner'): return None if not agent.planner: return None diff --git a/src/google/adk/flows/llm_flows/agent_transfer.py b/src/google/adk/flows/llm_flows/agent_transfer.py index fcb27d4a..b63996c7 100644 --- a/src/google/adk/flows/llm_flows/agent_transfer.py +++ b/src/google/adk/flows/llm_flows/agent_transfer.py @@ -40,9 +40,7 @@ class _AgentTransferLlmRequestProcessor(BaseLlmRequestProcessor): async def run_async( self, invocation_context: InvocationContext, llm_request: LlmRequest ) -> AsyncGenerator[Event, None]: - from ...agents.llm_agent import LlmAgent - - if not isinstance(invocation_context.agent, LlmAgent): + if not hasattr(invocation_context.agent, 'disallow_transfer_to_parent'): return transfer_targets = _get_transfer_targets(invocation_context.agent) @@ -141,12 +139,12 @@ If neither you nor the other agents are best for the question, transfer to your def _get_transfer_targets(agent: LlmAgent) -> list[BaseAgent]: - from ...agents.llm_agent import LlmAgent - result = [] result.extend(agent.sub_agents) - if not agent.parent_agent or not isinstance(agent.parent_agent, LlmAgent): + if not agent.parent_agent or not hasattr( + agent.parent_agent, 'disallow_transfer_to_parent' + ): return result if not agent.disallow_transfer_to_parent: diff --git a/src/google/adk/flows/llm_flows/base_llm_flow.py b/src/google/adk/flows/llm_flows/base_llm_flow.py index d4af6937..f1c1cce8 100644 --- a/src/google/adk/flows/llm_flows/base_llm_flow.py +++ b/src/google/adk/flows/llm_flows/base_llm_flow.py @@ -520,12 +520,11 @@ class BaseLlmFlow(ABC): async def _preprocess_async( self, invocation_context: InvocationContext, llm_request: LlmRequest ) -> AsyncGenerator[Event, None]: - from ...agents.llm_agent import LlmAgent - agent = invocation_context.agent - if not isinstance(agent, LlmAgent): + if not hasattr(agent, 'tools') or not hasattr(agent, 'canonical_model'): raise TypeError( - f'Expected agent to be an LlmAgent, but got {type(agent)}' + 'Expected agent to have tools and canonical_model attributes,' + f' but got {type(agent)}' ) # Runs processors. @@ -973,8 +972,6 @@ class BaseLlmFlow(ABC): llm_request: LlmRequest, model_response_event: Event, ) -> Optional[LlmResponse]: - from ...agents.llm_agent import LlmAgent - agent = invocation_context.agent callback_context = CallbackContext( @@ -1010,8 +1007,6 @@ class BaseLlmFlow(ABC): llm_response: LlmResponse, model_response_event: Event, ) -> Optional[LlmResponse]: - from ...agents.llm_agent import LlmAgent - agent = invocation_context.agent # Add grounding metadata to the response if needed. @@ -1130,12 +1125,11 @@ class BaseLlmFlow(ABC): A generator of LlmResponse. """ - from ...agents.llm_agent import LlmAgent - agent = invocation_context.agent - if not isinstance(agent, LlmAgent): + if not hasattr(agent, 'canonical_on_model_error_callbacks'): raise TypeError( - f'Expected agent to be an LlmAgent, but got {type(agent)}' + 'Expected agent to have canonical_on_model_error_callbacks' + f' attribute, but got {type(agent)}' ) async def _run_on_model_error_callbacks( @@ -1190,6 +1184,10 @@ class BaseLlmFlow(ABC): raise model_error def __get_llm(self, invocation_context: InvocationContext) -> BaseLlm: - from ...agents.llm_agent import LlmAgent - - return cast(LlmAgent, invocation_context.agent).canonical_model + agent = invocation_context.agent + if not hasattr(agent, 'canonical_model'): + raise TypeError( + 'Expected agent to have canonical_model attribute,' + f' but got {type(agent)}' + ) + return agent.canonical_model diff --git a/src/google/adk/flows/llm_flows/instructions.py b/src/google/adk/flows/llm_flows/instructions.py index 1e7e43a6..0e3321b7 100644 --- a/src/google/adk/flows/llm_flows/instructions.py +++ b/src/google/adk/flows/llm_flows/instructions.py @@ -73,7 +73,6 @@ async def _build_instructions( llm_request: The LlmRequest to populate with instructions. """ from ...agents.base_agent import BaseAgent - from ...agents.llm_agent import LlmAgent agent = invocation_context.agent @@ -81,7 +80,10 @@ async def _build_instructions( # Handle global instructions (DEPRECATED - use GlobalInstructionPlugin instead) # TODO: Remove this code block when global_instruction field is removed - if isinstance(root_agent, LlmAgent) and root_agent.global_instruction: + if ( + hasattr(root_agent, 'global_instruction') + and root_agent.global_instruction + ): raw_si, bypass_state_injection = ( await root_agent.canonical_global_instruction( ReadonlyContext(invocation_context) diff --git a/src/google/adk/flows/llm_flows/interactions_processor.py b/src/google/adk/flows/llm_flows/interactions_processor.py index 60dc7543..6a180888 100644 --- a/src/google/adk/flows/llm_flows/interactions_processor.py +++ b/src/google/adk/flows/llm_flows/interactions_processor.py @@ -46,12 +46,11 @@ class InteractionsRequestProcessor(BaseLlmRequestProcessor): Yields: Event: No events are yielded by this processor """ - from ...agents.llm_agent import LlmAgent from ...models.google_llm import Gemini agent = invocation_context.agent # Only process if using Gemini with interactions API - if not isinstance(agent, LlmAgent): + if not hasattr(agent, 'canonical_model'): return model = agent.canonical_model if not isinstance(model, Gemini): diff --git a/src/google/adk/runners.py b/src/google/adk/runners.py index 39fc71d7..921afee6 100644 --- a/src/google/adk/runners.py +++ b/src/google/adk/runners.py @@ -39,7 +39,6 @@ from .agents.context_cache_config import ContextCacheConfig from .agents.invocation_context import InvocationContext from .agents.invocation_context import new_invocation_context_id from .agents.live_request_queue import LiveRequestQueue -from .agents.llm_agent import LlmAgent from .agents.run_config import RunConfig from .apps.app import App from .apps.app import ResumabilityConfig @@ -1143,8 +1142,8 @@ class Runner: """ agent = agent_to_run while agent: - if not isinstance(agent, LlmAgent): - # Only LLM-based Agent can provide agent transfer capability. + if not hasattr(agent, 'disallow_transfer_to_parent'): + # Only agents with transfer capability can transfer. return False if agent.disallow_transfer_to_parent: return False @@ -1393,7 +1392,7 @@ class Runner: run_config = run_config or RunConfig() invocation_id = invocation_id or new_invocation_context_id() - if run_config.support_cfc and isinstance(self.agent, LlmAgent): + if run_config.support_cfc and hasattr(self.agent, 'canonical_model'): model_name = self.agent.canonical_model.model if not model_name.startswith('gemini-2'): raise ValueError( @@ -1487,7 +1486,7 @@ class Runner: def _collect_toolset(self, agent: BaseAgent) -> set[BaseToolset]: toolsets = set() - if isinstance(agent, LlmAgent): + if hasattr(agent, 'tools'): for tool_union in agent.tools: if isinstance(tool_union, BaseToolset): toolsets.add(tool_union)