Skip to content
24 changes: 20 additions & 4 deletions src/google/adk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,27 @@
# limitations under the License.

from __future__ import annotations
from typing import TYPE_CHECKING

from . import version
from .agents.context import Context
from .agents.llm_agent import Agent
from .runners import Runner
if TYPE_CHECKING:
from .agents.context import Context
from .agents.llm_agent import Agent
from .runners import Runner
else:
import importlib

_LAZY_IMPORTS = {
"Agent": ".agents.llm_agent",
"Context": ".agents.context",
"Runner": ".runners",
}

def __getattr__(name: str):
if name in _LAZY_IMPORTS:
module = importlib.import_module(_LAZY_IMPORTS[name], __name__)
return getattr(module, name)
raise AttributeError(f"module {__name__} has no attribute {name}")

from . import version
__version__ = version.__version__
__all__ = ["Agent", "Context", "Runner"]
75 changes: 51 additions & 24 deletions src/google/adk/agents/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,57 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from .base_agent import BaseAgent
from .context import Context
from .invocation_context import InvocationContext
from .live_request_queue import LiveRequest
from .live_request_queue import LiveRequestQueue
from .llm_agent import Agent
from .llm_agent import LlmAgent
from .loop_agent import LoopAgent
from .mcp_instruction_provider import McpInstructionProvider
from .parallel_agent import ParallelAgent
from .run_config import RunConfig
from .sequential_agent import SequentialAgent
from __future__ import annotations
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from .base_agent import BaseAgent
from .context import Context
from .invocation_context import InvocationContext
from .live_request_queue import LiveRequest
from .live_request_queue import LiveRequestQueue
from .llm_agent import Agent
from .llm_agent import LlmAgent
from .loop_agent import LoopAgent
from .mcp_instruction_provider import McpInstructionProvider
from .parallel_agent import ParallelAgent
from .run_config import RunConfig
from .sequential_agent import SequentialAgent
else:
import importlib

_LAZY_IMPORTS = {
"Agent": ".llm_agent",
"BaseAgent": ".base_agent",
"Context": ".context",
"InvocationContext": ".invocation_context",
"LiveRequest": ".live_request_queue",
"LiveRequestQueue": ".live_request_queue",
"LlmAgent": ".llm_agent",
"LoopAgent": ".loop_agent",
"McpInstructionProvider": ".mcp_instruction_provider",
"ParallelAgent": ".parallel_agent",
"RunConfig": ".run_config",
"SequentialAgent": ".sequential_agent",
}

def __getattr__(name: str):
if name in _LAZY_IMPORTS:
module = importlib.import_module(_LAZY_IMPORTS[name], __name__)
return getattr(module, name)
raise AttributeError(f"module {__name__} has no attribute {name}")

__all__ = [
'Agent',
'BaseAgent',
'Context',
'LlmAgent',
'LoopAgent',
'McpInstructionProvider',
'ParallelAgent',
'SequentialAgent',
'InvocationContext',
'LiveRequest',
'LiveRequestQueue',
'RunConfig',
"Agent",
"BaseAgent",
"Context",
"InvocationContext",
"LiveRequest",
"LiveRequestQueue",
"LlmAgent",
"LoopAgent",
"McpInstructionProvider",
"ParallelAgent",
"RunConfig",
"SequentialAgent",
]
28 changes: 28 additions & 0 deletions tests/unittests/test_lazy_loading.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import sys
import unittest
import google.adk

class TestLazyLoading(unittest.TestCase):
def test_agent_not_loaded(self):
# Before accessing Agent, it shouldn't be in sys.modules
self.assertNotIn("google.adk.agents.llm_agent", sys.modules)

# Accessing Agent
_ = google.adk.Agent

# Now it should be loaded
self.assertIn("google.adk.agents.llm_agent", sys.modules)