Skip to content

Conversation

@JacksonMei
Copy link
Collaborator

No description provided.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @JacksonMei, 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 expands the AEnv command-line interface by introducing a comprehensive set of commands for managing environment instances. It enables users to perform full lifecycle operations such as creating, inspecting, listing, and deleting instances directly from the CLI, thereby streamlining the interaction with the AEnv system. The changes involve both new CLI implementation and corresponding backend API and controller modifications to support these new capabilities.

Highlights

  • New CLI 'instance' Command: Introduced a new top-level CLI command aenv instance to manage the lifecycle of environment instances, including creation, retrieval, listing, and deletion.
  • Instance Creation Functionality: Added aenv instance create subcommand, allowing users to deploy new environment instances with options for data sources, time-to-live (TTL), environment variables, command-line arguments, and authentication. It also supports keeping instances alive or automatically releasing them.
  • Instance Query and Listing: Implemented aenv instance info, aenv instance get, and aenv instance list subcommands to retrieve detailed information about specific instances by ID or name, and to list all running instances with filtering capabilities by environment name and version.
  • Instance Deletion: Provided aenv instance delete subcommand for terminating running environment instances by their ID, including a confirmation prompt for safety.
  • Backend API and Controller Enhancements: Updated the backend API and Kubernetes controller to support the new CLI functionalities. This includes enriching the pod listing response with environment name, version, and IP, and ensuring that new pods are labeled with aenv-name and aenv-version for better discoverability and metadata management.

🧠 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.

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 CLI support for managing AEnv instances, including create, get, list, and delete operations. The changes span both the Python CLI and the Go backend services. My review focuses on improving configuration handling consistency in the CLI, addressing a performance issue in the list command, and correcting potentially misleading data in the API response. Overall, the changes are a great addition, and with a few adjustments, they will be even more robust and efficient.

Comment on lines 645 to 704
elif output == "table":
# Prepare table data
table_data = []
for instance in instances_list:
instance_id = instance.get("id", "")
if not instance_id:
continue

# Try to get detailed info for each instance
detailed_info = _get_instance_from_api(system_url, instance_id)

# Use detailed info if available, otherwise use list data
if detailed_info:
env_info = detailed_info.get("env") or {}
else:
env_info = instance.get("env") or {}

env_name = env_info.get("name") if env_info else None
env_version = env_info.get("version") if env_info else None

# If env is None, try to extract from instance ID
if not env_name and instance_id:
parts = instance_id.split("-")
if len(parts) >= 2:
env_name = parts[0]

# Get IP from detailed info or list data
if detailed_info:
ip = detailed_info.get("ip") or ""
else:
ip = instance.get("ip") or ""

if not ip:
ip = "-"

# Get status from detailed info or list data
status = (
detailed_info.get("status")
if detailed_info
else instance.get("status") or "-"
)

# Get created_at from list data
created_at = instance.get("created_at") or "-"

table_data.append(
{
"Instance ID": instance_id,
"Environment": env_name or "-",
"Version": env_version or "-",
"Status": status,
"IP": ip,
"Created At": created_at,
}
)

if table_data:
console.print(tabulate(table_data, headers="keys", tablefmt="grid"))
else:
console.print("📭 No running instances found")
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The current implementation of list_instances makes an additional API call (_get_instance_from_api) for each instance returned by the initial list call. This is an example of an N+1 query problem and can lead to significant performance issues when there are many instances. The backend has been updated to include detailed information in the list response, so these extra calls are unnecessary. You should refactor this to process the data from the initial list response directly.

    elif output == "table":
        # Prepare table data
        table_data = []
        for instance_data in instances_list:
            instance_id = instance_data.get("id", "")
            if not instance_id:
                continue

            env_info = instance_data.get("env") or {}
            env_name = env_info.get("name")
            env_version = env_info.get("version")

            # Fallback for older API versions or if env block is missing
            if not env_name and instance_id:
                parts = instance_id.split("-")
                if len(parts) >= 2:
                    env_name = parts[0]

            table_data.append(
                {
                    "Instance ID": instance_id,
                    "Environment": env_name or "-",
                    "Version": env_version or "-",
                    "Status": instance_data.get("status", "-"),
                    "IP": instance_data.get("ip") or "-",
                    "Created At": instance_data.get("created_at") or "-",
                }
            )

        if table_data:
            console.print(tabulate(table_data, headers="keys", tablefmt="grid"))
        else:
            console.print("📭 No running instances found")

Comment on lines 103 to 108
def _get_system_url() -> str:
"""Get AEnv system URL from environment variable or config."""
system_url = os.getenv("AENV_SYSTEM_URL")
if not system_url:
system_url = "http://localhost:8080"
return _make_api_url(system_url, port=8080)
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 docstring for _get_system_url mentions that it gets the URL from environment variables or config, but the implementation only checks the environment variable AENV_SYSTEM_URL. This is inconsistent with other parts of the CLI, like _get_api_headers, which do check the configuration file. To ensure consistent behavior, this function should also retrieve the system URL from the CLI configuration. This will allow users to configure the system URL in one central place.

Suggested change
def _get_system_url() -> str:
"""Get AEnv system URL from environment variable or config."""
system_url = os.getenv("AENV_SYSTEM_URL")
if not system_url:
system_url = "http://localhost:8080"
return _make_api_url(system_url, port=8080)
def _get_system_url() -> str:
"""Get AEnv system URL from environment variable or config."""
config_manager = get_config_manager()
hub_config = config_manager.get_hub_config()
system_url = hub_config.get("hub_backend") or os.getenv("AENV_SYSTEM_URL")
if not system_url:
system_url = "http://localhost:8080"
return _make_api_url(system_url, port=8080)

Comment on lines 391 to 397
# Get API key from env if not provided
if not api_key:
api_key = os.getenv("AENV_API_KEY")

# Get system URL from env if not provided
if not system_url:
system_url = os.getenv("AENV_SYSTEM_URL")
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 logic for retrieving the API key and system URL only considers command-line options and environment variables, but it omits checking the CLI configuration file. This is inconsistent with how other configurations are handled (e.g., in _get_api_headers). For a better user experience and more consistent configuration management, you should also check the configuration file for these values.

Suggested change
# Get API key from env if not provided
if not api_key:
api_key = os.getenv("AENV_API_KEY")
# Get system URL from env if not provided
if not system_url:
system_url = os.getenv("AENV_SYSTEM_URL")
# Get API key from config/env if not provided
config_manager = get_config_manager()
hub_config = config_manager.get_hub_config()
if not api_key:
api_key = hub_config.get("api_key") or os.getenv("AENV_API_KEY")
# Get system URL from config/env if not provided
if not system_url:
system_url = hub_config.get("hub_backend") or os.getenv("AENV_SYSTEM_URL")

Comment on lines 513 to 519
# Get API key from env if not provided
if not api_key:
api_key = os.getenv("AENV_API_KEY")

# Get system URL from env if not provided
if not system_url:
system_url = os.getenv("AENV_SYSTEM_URL")
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Similar to the create command, the logic for retrieving the API key and system URL here only considers command-line options and environment variables, but it omits checking the CLI configuration file. For consistency and better configuration management, you should also check the configuration file for these values.

Suggested change
# Get API key from env if not provided
if not api_key:
api_key = os.getenv("AENV_API_KEY")
# Get system URL from env if not provided
if not system_url:
system_url = os.getenv("AENV_SYSTEM_URL")
# Get API key from config/env if not provided
config_manager = get_config_manager()
hub_config = config_manager.get_hub_config()
if not api_key:
api_key = hub_config.get("api_key") or os.getenv("AENV_API_KEY")
# Get system URL from config/env if not provided
if not system_url:
system_url = hub_config.get("hub_backend") or os.getenv("AENV_SYSTEM_URL")

Comment on lines 290 to 301
createdAtStr := podData.CreatedAt.Format("2006-01-02 15:04:05")
nowStr := time.Now().Format("2006-01-02 15:04:05")

instances[i] = &models.EnvInstance{
ID: podData.ID,
Env: env,
Status: podData.Status,
CreatedAt: createdAtStr,
UpdatedAt: nowStr,
IP: podData.IP,
TTL: podData.TTL,
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Setting UpdatedAt to time.Now() is misleading, as it reflects the time of the API call rather than when the resource was last modified. This can cause confusion for clients of the API. Since the pod data from the controller does not seem to provide an update timestamp, it would be more accurate and less confusing to set UpdatedAt to the same value as CreatedAt.

Suggested change
createdAtStr := podData.CreatedAt.Format("2006-01-02 15:04:05")
nowStr := time.Now().Format("2006-01-02 15:04:05")
instances[i] = &models.EnvInstance{
ID: podData.ID,
Env: env,
Status: podData.Status,
CreatedAt: createdAtStr,
UpdatedAt: nowStr,
IP: podData.IP,
TTL: podData.TTL,
}
// Format CreatedAt time
createdAtStr := podData.CreatedAt.Format("2006-01-02 15:04:05")
instances[i] = &models.EnvInstance{
ID: podData.ID,
Env: env,
Status: podData.Status,
CreatedAt: createdAtStr,
UpdatedAt: createdAtStr,
IP: podData.IP,
TTL: podData.TTL,
}

Copy link
Collaborator

@lanmaoxinqing lanmaoxinqing left a comment

Choose a reason for hiding this comment

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

LGTM

@JacksonMei JacksonMei changed the title AEnv CLI support instance create/get/list/delete AEnv CLI support instance create/get/list/delete and system_url/owner config Jan 15, 2026
@lanmaoxinqing lanmaoxinqing merged commit 0a53704 into main Jan 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants