Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ class GeminiPlugin : IPlugin, DocumentationExtension {
does by embedding every chunk of the project with this model. It
is a separate setting because no Gemini model does both: this list
holds the models that advertise <code>embedContent</code>, and the
<b>Gemini Model</b> list above holds those that advertise
<b>Model</b> list above holds those that advertise
<code>generateContent</code>.</p>
<p>Changing it changes the vector space, so the project is indexed
again from scratch. Vectors from two different models are not
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ internal class SecretRevealController(
/**
* Take over [box]'s end icon and mask the field.
*
* The drawable is set here rather than in the layout because Material 1.10 never reads
* `app:endIconDrawable`, so a custom end icon declared in XML draws blank.
* The drawable is set here rather than in the layout because an end icon declared as
* `app:endIconDrawable` draws blank inside the host.
*/
fun attach() {
box.endIconMode = TextInputLayout.END_ICON_CUSTOM
Expand Down
10 changes: 10 additions & 0 deletions plugins/AI-Agent-Gemini/src/main/res/drawable/ic_dropdown.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M7,10l5,5 5,-5z" />
</vector>
138 changes: 117 additions & 21 deletions plugins/AI-Agent-Gemini/src/main/res/layout/fragment_gemini_settings.xml
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Material fields and buttons throughout, on the shared house spacing scale, so this pane and the
OpenAI one read as the same screen with a different backend behind it. The root android:theme is
what guarantees the plugin's own button/input styles win over whatever theme the host builds the
inflation Context from.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:orientation="vertical"
android:theme="@style/ThemeOverlay.Plugin">

<!-- API key. Collapses to the status line once a key is stored. -->

<TextView
android:id="@+id/gemini_api_key_status_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?android:attr/textColorSecondary"
android:layout_marginBottom="@dimen/space_sm"
android:textAppearance="@style/Plugin.Text.Body"
android:visibility="gone" />

<LinearLayout
Expand All @@ -20,19 +29,18 @@
android:orientation="vertical">

<TextView
android:id="@+id/gemini_api_key_label"
style="@style/Plugin.SectionHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/label_gemini_api_key"
android:textAppearance="?android:attr/textAppearanceSmall"
android:paddingBottom="4dp"/>
android:text="@string/label_gemini_api_key" />

<!--
The reveal toggle is the box's own end icon rather than the loose ImageButton that used to
sit beside the field: the icon has a real touch target, and it is the same control the
other AI plugins' credential fields carry. Nothing endIcon-related is declared here —
SecretRevealController sets the mode, drawable, description and listener in code, because
Material 1.10 never reads app:endIconDrawable and a custom icon declared in XML draws
blank.
an end icon declared as app:endIconDrawable here draws blank inside the host.
-->
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/gemini_api_key_box"
Expand All @@ -53,52 +61,140 @@

<TextView
android:id="@+id/gemini_key_verification_text"
style="@style/Plugin.StatusLine"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:drawablePadding="6dp"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
android:layout_marginTop="@dimen/space_sm"
android:visibility="gone" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginTop="@dimen/space_md"
android:orientation="horizontal">

<Button
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_clear_api_key"
style="@style/PluginButton.Filled"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/btn_clear_api_key"
android:visibility="gone" />

<Button
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_edit_api_key"
style="@style/PluginButton.Filled"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginStart="@dimen/space_sm"
android:layout_weight="1"
android:text="@string/btn_edit_api_key"
android:visibility="gone" />

<Button
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_save_api_key"
style="@style/PluginButton.Filled"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/btn_save_api_key" />

</LinearLayout>

<Button
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_get_free_key"
style="@style/PluginButton.Filled"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginTop="@dimen/space_sm"
android:text="@string/btn_get_free_key" />

<!-- Model. One dropdown, the same control the OpenAI pane uses: the catalog is whatever the
key can reach, so the list is the only way to change it. The chevron is not declared here —
declared as app:endIconDrawable it draws blank inside the host, so
setupDropdownEndIcon() sets it on every box in code. -->

<TextView
android:id="@+id/gemini_model_label"
style="@style/Plugin.SectionHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/space_xl"
android:text="@string/label_gemini_model" />

<com.google.android.material.textfield.TextInputLayout
android:id="@+id/gemini_model_box"
style="@style/PluginTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hint_gemini_model"
app:endIconContentDescription="@string/cd_show_models"
app:endIconMode="custom">

<AutoCompleteTextView
android:id="@+id/gemini_model_input"
style="@style/PluginTextInputEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:completionThreshold="0"
android:inputType="none"
android:popupBackground="@color/plugin_surface" />
</com.google.android.material.textfield.TextInputLayout>

<TextView
android:id="@+id/gemini_model_hint_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/space_xs"
android:text="@string/hint_gemini_model_help"
android:textAppearance="@style/Plugin.Text.Small" />

<!-- Embedding model. The other half of the same catalog: semantic search embeds with this one,
never with the chat model above. -->

<TextView
android:id="@+id/gemini_embedding_model_label"
style="@style/Plugin.SectionHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/space_xl"
android:text="@string/label_gemini_embedding_model" />

<com.google.android.material.textfield.TextInputLayout
android:id="@+id/gemini_embedding_model_box"
style="@style/PluginTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hint_gemini_embedding_model"
app:endIconContentDescription="@string/cd_show_embedding_models"
app:endIconMode="custom">

<AutoCompleteTextView
android:id="@+id/gemini_embedding_model_input"
style="@style/PluginTextInputEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:completionThreshold="0"
android:inputType="none"
android:popupBackground="@color/plugin_surface" />
</com.google.android.material.textfield.TextInputLayout>

<TextView
android:id="@+id/gemini_embedding_model_hint_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/space_xs"
android:text="@string/hint_gemini_embedding_model_help"
android:textAppearance="@style/Plugin.Text.Small" />

<!-- One Refresh for both pickers: a single catalog walk fills both lists. -->
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_refresh_models"
style="@style/PluginButton.Filled"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/space_md"
android:text="@string/refresh_models" />

</LinearLayout>
15 changes: 15 additions & 0 deletions plugins/AI-Agent-Gemini/src/main/res/layout/item_dropdown.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
One row of the model dropdown. The plugin's own item layout rather than
android.R.layout.simple_list_item_1, whose text color comes from the framework theme in effect
when the popup window is built — which is not reliably the one the pane is drawn in.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:minHeight="@dimen/touch_target_min"
android:paddingHorizontal="@dimen/space_lg"
android:paddingVertical="@dimen/space_md"
android:textAppearance="@style/Plugin.Text.Body" />
21 changes: 21 additions & 0 deletions plugins/AI-Agent-Gemini/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Spacing, radius and type scale shared with the other CoGo house plugins (see
client-time-tracker), so this pane sits on the same grid as the rest of the IDE's plugin UI
instead of the ad-hoc 4/8/24dp margins it used before.
-->
<resources>
<dimen name="space_xs">4dp</dimen>
<dimen name="space_sm">8dp</dimen>
<dimen name="space_md">12dp</dimen>
<dimen name="space_lg">16dp</dimen>
<dimen name="space_xl">24dp</dimen>

<dimen name="radius_md">8dp</dimen>

<dimen name="text_micro">11sp</dimen>
<dimen name="text_small">13sp</dimen>
<dimen name="text_body">15sp</dimen>

<dimen name="touch_target_min">48dp</dimen>
</resources>
15 changes: 11 additions & 4 deletions plugins/AI-Agent-Gemini/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<string name="gemini_error_failed_reason">The Gemini request failed. %1$s</string>

<!-- Settings pane this backend contributes (see GeminiSettingsFragment) -->
<string name="label_gemini_api_key">Gemini API Key</string>
<string name="label_gemini_api_key">API Key</string>
<string name="hint_gemini_api_key">Enter your Gemini API key</string>
<!-- Reveal toggle on the masked credential field. Deliberately the same wording in
every AI plugin: one control, one announcement, whatever the field holds. -->
Expand Down Expand Up @@ -51,9 +51,16 @@
<string name="msg_key_hint_edit_first">Copied a new key? Tap Edit, then paste it into the field.</string>
<string name="msg_no_browser_for_key">No browser available. The link was copied — open it on another device: %s</string>
<string name="msg_key_link_copy_failed">Couldn\'t open a browser. Get your key at %s</string>
<string name="label_gemini_model">Gemini Model</string>
<string name="label_gemini_embedding_model">Gemini Embedding Model</string>
<string name="current_model">Current: %s</string>
<string name="label_gemini_model">Model</string>
<string name="hint_gemini_model">Gemini model</string>
<string name="cd_show_models">Show the model list</string>
<string name="hint_gemini_model_help">Refresh to list the models your key can reach.</string>
<string name="hint_gemini_model_live">Tap to pick from the models this key can reach.</string>
<string name="label_gemini_embedding_model">Embedding Model</string>
<string name="hint_gemini_embedding_model">Gemini embedding model</string>
<string name="cd_show_embedding_models">Show the embedding model list</string>
<string name="hint_gemini_embedding_model_help">Used by semantic search, never for chat. Refresh to list the embedding models your key can reach.</string>
<string name="hint_gemini_embedding_model_live">Tap to pick from the embedding models this key can reach.</string>
<string name="refresh_models">Refresh Models</string>
<string name="loading">Loading…</string>
<string name="model_changed">Model changed to %s</string>
Expand Down
Loading
Loading