Skip to content

Conversation

@jayy-77
Copy link

@jayy-77 jayy-77 commented Feb 12, 2026

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

2. Or, if no issue exists, describe the change:

If applicable, please follow the issue templates to provide as much detail as
possible.

Problem:
A clear and concise description of what the problem is.

Solution:
A clear and concise description of what you want to happen and why you choose
this solution.

Testing Plan

Please describe the tests that you ran to verify your changes. This is required
for all PRs that are not small documentation or typo fixes.

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

Please include a summary of passed pytest results.

Manual End-to-End (E2E) Tests:

Please provide instructions on how to manually test your changes, including any
necessary setup or configuration. Please provide logs or screenshots to help
reviewers better understand the fix.

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

Additional context

Add any other context or screenshots about the feature request here.

@adk-bot
Copy link
Collaborator

adk-bot commented Feb 12, 2026

Response from ADK Triaging Agent

Hello @jayy-77, thank you for creating this PR!

Could you please provide a testing plan for your changes? This will help reviewers to review your PR more efficiently.

For more details, please see the contribution guidelines. Thanks!

@adk-bot adk-bot added the services [Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc label Feb 12, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @jayy-77, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the configuration flexibility for Google Cloud project and location settings within Vertex AI services. By implementing a lazy resolution mechanism, these critical parameters no longer need to be strictly defined at initialization. Instead, they can be dynamically resolved at runtime from environment variables or .env files, making the system more adaptable to different deployment environments and reducing the need for explicit configuration in code.

Highlights

  • Lazy Resolution for GCP Configuration: Implemented lazy resolution for Google Cloud project and location configurations within Vertex AI services, allowing these parameters to be resolved at runtime from environment variables or .env files.
  • Updated _parse_agent_engine_kwargs: Modified _parse_agent_engine_kwargs to defer project and location loading, instead passing agents_dir for subsequent lazy resolution.
  • New _resolve_config Method: Introduced a _resolve_config method in VertexAiMemoryBankService and VertexAiSessionService to dynamically load project/location settings upon first use, supporting various configuration sources.
  • Service Constructor and Method Updates: Updated constructors and core service methods in VertexAiMemoryBankService and VertexAiSessionService to integrate the new lazy resolution mechanism, improving configuration flexibility.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • src/google/adk/cli/service_registry.py
    • Removed immediate loading of project and location when an agent engine ID is provided without a full URI.
    • Added agents_dir to the returned dictionary in _parse_agent_engine_kwargs to facilitate lazy resolution.
    • Included agents_dir in the returned dictionary when a full resource name is parsed.
  • src/google/adk/memory/vertex_ai_memory_bank_service.py
    • Added agents_dir as an optional parameter to the __init__ method.
    • Updated docstrings for project and location to indicate lazy resolution support.
    • Initialized _agents_dir and _config_resolved attributes for managing configuration state.
    • Deferred the resolution of _express_mode_api_key until configuration is resolved.
    • Implemented a new _resolve_config method to handle dynamic loading of project and location from environment variables or .env files.
    • Integrated calls to _resolve_config before search_memory operations to ensure configuration is available.
  • src/google/adk/sessions/vertex_ai_session_service.py
    • Added agents_dir as an optional parameter to the __init__ method.
    • Updated docstrings for project and location to indicate lazy resolution support.
    • Initialized _agents_dir and _config_resolved attributes for managing configuration state.
    • Deferred the resolution of _express_mode_api_key until configuration is resolved.
    • Implemented a new _resolve_config method to handle dynamic loading of project and location, supporting agent-specific .env files.
    • Integrated calls to _resolve_config before create_session, get_session, list_sessions, delete_session, and append_event operations.
Activity
  • No human activity (comments, reviews, approvals) has been recorded on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces lazy resolution for GCP project and location configurations, which is a good improvement. The implementation correctly defers loading this configuration until a service method is called in most cases.

However, I've identified a critical issue in VertexAiMemoryBankService where the add_session_to_memory and add_events_to_memory methods do not perform lazy resolution, which could lead to runtime errors if project/location are not provided at initialization. Since the relevant lines are not part of this pull request's changes, I am unable to add a specific comment there, but this should be addressed to fully complete the lazy resolution implementation.

I've also provided a few suggestions to improve code clarity and reduce duplication in the new _resolve_config methods.

Comment on lines +214 to +261
def _resolve_config(self) -> None:
"""Lazily resolves project and location if not provided at initialization.

This method is called on first use to resolve GCP configuration from:
1. Explicit environment variables (highest priority)
2. agents_dir root .env file
3. Parent directory .env files (walking upward)

Raises:
ValueError: If project or location cannot be resolved.
"""
if self._config_resolved:
return

import os

# If both are already set (either at init or via environment), we're done
if self._project and self._location:
self._config_resolved = True
self._express_mode_api_key = get_express_mode_api_key(
self._project, self._location, self._express_mode_api_key
)
return

# Try to load from environment and .env files
if self._agents_dir:
# Load from agents_dir root
from ..cli.utils import envs
envs.load_dotenv_for_agent("", self._agents_dir)

# Resolve from environment after loading .env
self._project = self._project or os.environ.get("GOOGLE_CLOUD_PROJECT")
self._location = self._location or os.environ.get("GOOGLE_CLOUD_LOCATION")

if not self._project or not self._location:
error_msg = (
"GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_LOCATION must be set. "
"You can set them via:\n"
" 1. Environment variables: GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_LOCATION\n"
" 2. .env file in your agents_dir\n"
" 3. Use full resource name: agentengine://projects/{project}/locations/{location}/reasoningEngines/{id}"
)
raise ValueError(error_msg)

self._config_resolved = True
self._express_mode_api_key = get_express_mode_api_key(
self._project, self._location, self._express_mode_api_key
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The _resolve_config method has some repeated logic for setting self._config_resolved and calling get_express_mode_api_key. This can be refactored to be more concise and follow the DRY (Don't Repeat Yourself) principle.

  def _resolve_config(self) -> None:
    """Lazily resolves project and location if not provided at initialization.
    
    This method is called on first use to resolve GCP configuration from:
    1. Explicit environment variables (highest priority)
    2. agents_dir root .env file
    3. Parent directory .env files (walking upward)
    
    Raises:
      ValueError: If project or location cannot be resolved.
    """
    if self._config_resolved:
      return
    
    import os
    
    if not (self._project and self._location):
      # Try to load from environment and .env files
      if self._agents_dir:
        # Load from agents_dir root
        from ..cli.utils import envs
        envs.load_dotenv_for_agent("", self._agents_dir)
      
      # Resolve from environment after loading .env
      self._project = self._project or os.environ.get("GOOGLE_CLOUD_PROJECT")
      self._location = self._location or os.environ.get("GOOGLE_CLOUD_LOCATION")
    
    if not self._project or not self._location:
      error_msg = (
          "GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_LOCATION must be set. "
          "You can set them via:\n"
          "  1. Environment variables: GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_LOCATION\n"
          "  2. .env file in your agents_dir\n"
          "  3. Use full resource name: agentengine://projects/{project}/locations/{location}/reasoningEngines/{id}"
      )
      raise ValueError(error_msg)
    
    self._config_resolved = True
    self._express_mode_api_key = get_express_mode_api_key(
        self._project, self._location, self._express_mode_api_key
    )

self._project, self._location, self._express_mode_api_key
)

def _get_api_client(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The return type hint for _get_api_client was removed in this change. Restoring it will improve code clarity and help static analysis tools. The method returns an AsyncClient.

  def _get_api_client(self) -> vertexai.AsyncClient:

Comment on lines +345 to +401
def _resolve_config(self, app_name: Optional[str] = None) -> None:
"""Lazily resolves project and location if not provided at initialization.

This method is called on first use to resolve GCP configuration from:
1. Explicit environment variables (highest priority)
2. Agent-specific .env file (if app_name and agents_dir provided)
3. agents_dir root .env file
4. Parent directory .env files (walking upward)

Args:
app_name: Optional app name to load agent-specific .env files.

Raises:
ValueError: If project or location cannot be resolved.
"""
if self._config_resolved:
return

import os

# If both are already set (either at init or via environment), we're done
if self._project and self._location:
self._config_resolved = True
self._express_mode_api_key = get_express_mode_api_key(
self._project, self._location, self._express_mode_api_key
)
return

# Try to load from environment and .env files
if self._agents_dir and app_name:
# Load agent-specific .env
from ..cli.utils import envs
envs.load_dotenv_for_agent(app_name, self._agents_dir)
elif self._agents_dir:
# Load from agents_dir root
from ..cli.utils import envs
envs.load_dotenv_for_agent("", self._agents_dir)

# Resolve from environment after loading .env
self._project = self._project or os.environ.get("GOOGLE_CLOUD_PROJECT")
self._location = self._location or os.environ.get("GOOGLE_CLOUD_LOCATION")

if not self._project or not self._location:
error_msg = (
"GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_LOCATION must be set. "
"You can set them via:\n"
" 1. Environment variables: GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_LOCATION\n"
" 2. .env file in your agent directory\n"
" 3. .env file in your agents_dir\n"
" 4. Use full resource name: agentengine://projects/{project}/locations/{location}/reasoningEngines/{id}"
)
raise ValueError(error_msg)

self._config_resolved = True
self._express_mode_api_key = get_express_mode_api_key(
self._project, self._location, self._express_mode_api_key
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This _resolve_config method has some repeated logic, similar to the one in VertexAiMemoryBankService. Additionally, the .env loading part can be cleaned up to avoid a repeated import. Refactoring this will improve readability and maintainability.

  def _resolve_config(self, app_name: Optional[str] = None) -> None:
    """Lazily resolves project and location if not provided at initialization.
    
    This method is called on first use to resolve GCP configuration from:
    1. Explicit environment variables (highest priority)
    2. Agent-specific .env file (if app_name and agents_dir provided)
    3. agents_dir root .env file
    4. Parent directory .env files (walking upward)
    
    Args:
      app_name: Optional app name to load agent-specific .env files.
    
    Raises:
      ValueError: If project or location cannot be resolved.
    """
    if self._config_resolved:
      return
    
    import os
    
    if not (self._project and self._location):
      # Try to load from environment and .env files
      if self._agents_dir:
        from ..cli.utils import envs
        if app_name:
          # Load agent-specific .env
          envs.load_dotenv_for_agent(app_name, self._agents_dir)
        else:
          # Load from agents_dir root
          envs.load_dotenv_for_agent("", self._agents_dir)
      
      # Resolve from environment after loading .env
      self._project = self._project or os.environ.get("GOOGLE_CLOUD_PROJECT")
      self._location = self._location or os.environ.get("GOOGLE_CLOUD_LOCATION")
    
    if not self._project or not self._location:
      error_msg = (
          "GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_LOCATION must be set. "
          "You can set them via:\n"
          "  1. Environment variables: GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_LOCATION\n"
          "  2. .env file in your agent directory\n"
          "  3. .env file in your agents_dir\n"
          "  4. Use full resource name: agentengine://projects/{project}/locations/{location}/reasoningEngines/{id}"
      )
      raise ValueError(error_msg)
    
    self._config_resolved = True
    self._express_mode_api_key = get_express_mode_api_key(
        self._project, self._location, self._express_mode_api_key
    )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

services [Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants