这是indexloc提供的服务,不要输入任何密码
Skip to content

Conversation

@abhipatel12
Copy link
Collaborator

@abhipatel12 abhipatel12 commented Sep 19, 2025

TLDR

This pull request introduces a new /model slash command that allows users to interactively select the Gemini model they want to use for their session. Executing the command opens a full-screen dialog where the user can choose between Auto (default), Pro, Flash, and Flash-Lite models.

This feature is conditionally enabled and will only be available when the useModelRouter setting is set to true in the user's configuration.

UI:

Screenshot 2025-09-19 at 4 01 17 PM

Co-authored by @miguelsolorio

Dive Deeper

This PR implements the /model command and its corresponding UI through several new components and hooks:

  • /model Command: A new SlashCommand (modelCommand.ts) is defined. Its action returns a dialog type, triggering the DialogManager to open the new ModelDialog.
  • ModelDialog.tsx: A new dialog component that displays the available models with descriptions. It utilizes a new generic, reusable component for the selection UI.
  • DescriptiveRadioButtonSelect.tsx: A reusable and keyboard-navigable component for selecting an option from a list where each item has a title and a description. It supports navigation with j/k, arrow keys, and number selection.
  • useModelCommand.ts: A new hook that encapsulates the state management for the model dialog (isModelDialogOpen, openModelDialog, closeModelDialog, handleModelSelect). It interacts with the Config service to persist the user's selection.
  • Conditional Loading: The BuiltinCommandLoader has been updated to only load the /model command if config.getUseModelRouter() returns true, effectively feature-gating the command.

Reviewer Test Plan

  1. Enable the Feature: In your settings.json, set useModelRouter: true:

    {
      "experimental": {
        "useModelRouter": true
      }
    }
  2. Launch the CLI: Run npm start.

  3. Open the Dialog: Type /model and press Enter.

  4. Verify UI: Confirm that the "Select Model" dialog appears, showing the list of available models.

  5. Test Keyboard Navigation:

    • Use the up/down arrow keys and j/k keys to navigate the list.
    • Press a number key (e.g., 2) to select the corresponding model.
    • Press Enter to confirm a selection.
    • Press Escape to close the dialog without making a change.
  6. Confirm Selection: After selecting a model with Enter or a number key, the dialog should close. You can re-open it to verify your selection is highlighted.

Testing Matrix

🍏 🪟 🐧
npm run
npx
Docker
Podman - -
Seatbelt - -

Linked issues / bugs

This PR makes progress on #6079

@abhipatel12 abhipatel12 requested a review from a team as a code owner September 19, 2025 20:02
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @abhipatel12, 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 enhances the CLI experience by providing users with an interactive way to choose their Gemini model. It integrates a new slash command, a dedicated UI dialog, and robust state management, all while ensuring the feature can be toggled via configuration. The changes aim to improve user control over the AI model used in their sessions.

Highlights

  • New /model Command: Introduces a new /model slash command allowing users to interactively select their preferred Gemini model (Auto, Pro, Flash, Flash-Lite) for their session.
  • Interactive Model Selection UI: A new full-screen ModelDialog component is implemented, utilizing a generic and reusable DescriptiveRadioButtonSelect component for keyboard-navigable option selection with titles and descriptions.
  • Feature Gating: The /model command is conditionally enabled and loaded only when the useModelRouter setting is set to true in the user's configuration, allowing for controlled rollout.
  • State Management Hook: A new useModelCommand hook encapsulates the state management for the model dialog, including opening, closing, and persisting the user's model selection via the Config service.
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

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.

@github-actions
Copy link

github-actions bot commented Sep 19, 2025

Size Change: +5.05 kB (+0.03%)

Total Size: 17.4 MB

Filename Size Change
./bundle/gemini.js 17.4 MB +5.05 kB (+0.03%)
ℹ️ View Unchanged
Filename Size
./bundle/sandbox-macos-permissive-closed.sb 1.03 kB
./bundle/sandbox-macos-permissive-open.sb 830 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB
./bundle/sandbox-macos-restrictive-closed.sb 3.29 kB
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB

compressed-size-action

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 a new /model slash command for interactive model selection, gated by a useModelRouter setting. The implementation is well-structured, adding a new reusable DescriptiveRadioButtonSelect component, a useModelCommand hook, and integrating them into the existing application architecture. My review identifies a critical bug and a high-severity issue within the new DescriptiveRadioButtonSelect component related to state management and props synchronization. Addressing these will significantly improve the robustness and reliability of this new feature.

Copy link
Contributor

@miguelsolorio miguelsolorio left a comment

Choose a reason for hiding this comment

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

Tested this locally and appears to work well. One minor mention, it might be nice to add in the history what model was used. This could done in a follow up, but I also wondered if this info should be visible by default for all users like:

Image

@jacob314
Copy link
Collaborator

Hello! This is a great addition to the CLI. The new /model command will be very useful for users who want to experiment with different models. The code is well-structured, and the tests are thorough.

I have a few suggestions that could make the code even better, mostly related to our React best practices as outlined in GEMINI.md.

1. Refactor ModelDialog.tsx to Avoid useEffect for State Syncing

In ModelDialog.tsx, a useEffect is used to keep the selectedModel state in sync with the ConfigContext. Our GEMINI.md guide recommends avoiding this pattern to prevent unnecessary re-renders.

We can refactor the component to derive the initial model directly from the context during rendering. This makes the data flow clearer and more efficient.

Suggestion:
Remove the useEffect and the selectedModel state. Instead, calculate the initialIndex for DescriptiveRadioButtonSelect directly from the config context. You can keep a state variable like highlightedModel to track the user's navigation within the dialog, which would be updated by the onHighlight callback.

2. Improve Numeric Input Logic in DescriptiveRadioButtonSelect.tsx

The current implementation for selecting items with number keys has a small bug. When the number of items is a multiple of 10 (e.g., 10, 20), it's not possible to select items like '2' or '3' directly, as the component incorrectly waits for a second digit.

Suggestion:
The logic can be made more robust by checking if the entered number could potentially form a larger, valid number. If not, the selection should be made immediately. For example, if there are 15 items and the user presses '2', we know they can't be trying to type '20', so we can select item 2 right away.

Prompt Engineering Reflection

It looks like this change was likely generated from a prompt similar to this:

"Create a new /model slash command that opens a dialog to let the user select a Gemini model. The dialog should be keyboard navigable and the selection should be saved to the configuration. This feature should only be enabled if the useModelRouter setting is true."

To get even better results next time, we could enhance the prompt by reminding the model of our specific coding standards:

"When building the React components, ensure that you follow the guidelines in GEMINI.md, particularly avoiding setting state within useEffect for props that can be derived during rendering."

disabled?: boolean;
}

export interface DescriptiveRadioButtonSelectProps<T> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

please refactor this to use composition and a common base class with the existing RadioButton class. There is a lot of duplicate logic and we will make future enhancements that should be adopted by both. Generally this is just a radio button class with nicer rendering of the inputs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This has been refactored after we made the changes to extract the logic using the BaseSelectionList. Lmk what you think

setIsModelDialogOpen(false);
}, []);

const handleModelSelect = useCallback(
Copy link
Collaborator

Choose a reason for hiding this comment

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

any reason to not just move this directly within modelDialog? it already knows about the config. Might as well not separate stuff that can just be in one place. will simplify appContainer rather than tangling it with impl details. as a follow up we should regularize all the openDialog, closeDialog spew in AppContainer with generic functionality for that for all dialogs rather than creating so much boilerplate.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

{ isActive: true },
);

const handleSelect = (model: string) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: why create this helper. just pass onSelect directly?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Left this b/c it combines two things (setting the model + closing dialog) and provides the useCallback optimization

config?.getModel() || DEFAULT_GEMINI_MODEL_AUTO,
);

useEffect(() => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this useEffect is a no-op. you are already passing in
config?.getModel in the useState.
Are you concerned about the case of the config changing while the dialog is open? Config should be fixed today so no need to check for that... probably have bigger problems if the config changes while the model dialog is open.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sounds good, removed this

Copy link
Collaborator Author

@abhipatel12 abhipatel12 left a comment

Choose a reason for hiding this comment

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

Made the changes! Let me know how this looks!

config?.getModel() || DEFAULT_GEMINI_MODEL_AUTO,
);

useEffect(() => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sounds good, removed this

{ isActive: true },
);

const handleSelect = (model: string) => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Left this b/c it combines two things (setting the model + closing dialog) and provides the useCallback optimization

disabled?: boolean;
}

export interface DescriptiveRadioButtonSelectProps<T> {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This has been refactored after we made the changes to extract the logic using the BaseSelectionList. Lmk what you think

setIsModelDialogOpen(false);
}, []);

const handleModelSelect = useCallback(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

@abhipatel12 abhipatel12 force-pushed the model-command branch 2 times, most recently from 1146334 to 6af89af Compare September 22, 2025 19:27
Copy link
Collaborator

@jacob314 jacob314 left a comment

Choose a reason for hiding this comment

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

lgtm

miguelsolorio and others added 6 commits September 23, 2025 11:14
This commit introduces a new `/model` slash command to the Gemini CLI.

When executed, this command opens a full-screen dialog that presents a numbered list of available models, each with a title and a description. This provides a user-friendly way to view and select different models within the CLI.

Key changes include:
- A new `modelCommand.ts` to define the `/model` command.
- A `ModelDialog.tsx` component to render the selection UI.
- A reusable `DescriptiveRadioButtonSelect.tsx` component for creating lists with titles and descriptions.
- Integration into the CLI's state management and command processing systems to handle dialog visibility.
@abhipatel12 abhipatel12 added this pull request to the merge queue Sep 23, 2025
Merged via the queue into main with commit 5151bed Sep 23, 2025
27 of 31 checks passed
@abhipatel12 abhipatel12 deleted the model-command branch September 23, 2025 16:54
vick08 pushed a commit to vick08/gemini-cli that referenced this pull request Sep 24, 2025
…-gemini#8940)

Co-authored-by: Miguel Solorio <miguel.solorio07@gmail.com>
thacio added a commit to thacio/auditaria that referenced this pull request Oct 4, 2025
giraffe-tree pushed a commit to giraffe-tree/gemini-cli that referenced this pull request Oct 10, 2025
…-gemini#8940)

Co-authored-by: Miguel Solorio <miguel.solorio07@gmail.com>
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.

4 participants