Skip to content

Commit 530c71b

Browse files
committed
feat(ui): Add configurable dimension for Gemini models
Replaces the dimension slider with a text input for better precision, addressing reviewer feedback. Adds validation for the dimension range and corrects all related UI text and translations.
1 parent 7a23d03 commit 530c71b

File tree

2 files changed

+51
-52
lines changed

2 files changed

+51
-52
lines changed

webview-ui/src/components/chat/CodeIndexPopover.tsx

Lines changed: 49 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,20 @@ const createValidationSchema = (provider: EmbedderProvider, t: any, models: any)
125125
.min(1, t("settings:codeIndex.validation.modelSelectionRequired")),
126126
codebaseIndexEmbedderModelDimension: z.number().optional(),
127127
})
128+
.refine(
129+
(data) => {
130+
const model = models?.gemini?.[data.codebaseIndexEmbedderModelId || ""]
131+
// If the model supports variable dimensions, a dimension must be provided.
132+
if (model?.minDimension && !data.codebaseIndexEmbedderModelDimension) {
133+
return false // Fails validation if dimension is required but not provided
134+
}
135+
return true
136+
},
137+
{
138+
message: t("settings:codeIndex.validation.modelDimensionRequired"),
139+
path: ["codebaseIndexEmbedderModelDimension"],
140+
},
141+
)
128142
.refine(
129143
(data) => {
130144
const model = models?.gemini?.[data.codebaseIndexEmbedderModelId || ""]
@@ -136,9 +150,15 @@ const createValidationSchema = (provider: EmbedderProvider, t: any, models: any)
136150
}
137151
return true
138152
},
139-
{
140-
message: t("settings:codeIndex.validation.invalidDimension"),
141-
path: ["codebaseIndexEmbedderModelDimension"],
153+
(data) => {
154+
const model = models?.gemini?.[data.codebaseIndexEmbedderModelId || ""]
155+
return {
156+
message: t("settings:codeIndex.validation.invalidDimension", {
157+
min: model?.minDimension,
158+
max: model?.maxDimension,
159+
}),
160+
path: ["codebaseIndexEmbedderModelDimension"],
161+
}
142162
},
143163
)
144164

@@ -216,16 +236,13 @@ export const CodeIndexPopover: React.FC<CodeIndexPopoverProps> = ({
216236
codebaseIndexEmbedderModelDimension:
217237
codebaseIndexConfig.codebaseIndexEmbedderModelDimension || modelProfile?.defaultDimension,
218238
codebaseIndexSearchMaxResults:
219-
codebaseIndexConfig.codebaseIndexSearchMaxResults ??
220-
CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_RESULTS,
239+
codebaseIndexConfig.codebaseIndexSearchMaxResults ?? CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_RESULTS,
221240
codebaseIndexSearchMinScore:
222-
codebaseIndexConfig.codebaseIndexSearchMinScore ??
223-
CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_MIN_SCORE,
241+
codebaseIndexConfig.codebaseIndexSearchMinScore ?? CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_MIN_SCORE,
224242
// Keys are initially set to empty and populated by a separate effect.
225243
codeIndexOpenAiKey: "",
226244
codeIndexQdrantApiKey: "",
227-
codebaseIndexOpenAiCompatibleBaseUrl:
228-
codebaseIndexConfig.codebaseIndexOpenAiCompatibleBaseUrl || "",
245+
codebaseIndexOpenAiCompatibleBaseUrl: codebaseIndexConfig.codebaseIndexOpenAiCompatibleBaseUrl || "",
229246
codebaseIndexOpenAiCompatibleApiKey: "",
230247
codebaseIndexGeminiApiKey: "",
231248
}
@@ -971,55 +988,35 @@ export const CodeIndexPopover: React.FC<CodeIndexPopoverProps> = ({
971988
currentSettings.codebaseIndexEmbedderModelId
972989
]
973990

974-
// Conditionally render the dimension slider only for Gemini models
975-
// that explicitly define a min and max dimension in their profile.
976991
if (
977992
selectedModelProfile?.minDimension &&
978993
selectedModelProfile?.maxDimension
979994
) {
980995
return (
981996
<div className="space-y-2">
982-
<div className="flex items-center gap-2">
983-
<label className="text-sm font-medium">
984-
{t("settings:codeIndex.modelDimensionLabel")}
985-
</label>
986-
</div>
987-
<div className="flex items-center gap-2">
988-
<Slider
989-
min={selectedModelProfile.minDimension}
990-
max={selectedModelProfile.maxDimension}
991-
step={1}
992-
value={[
993-
currentSettings.codebaseIndexEmbedderModelDimension ??
994-
selectedModelProfile.defaultDimension ??
995-
selectedModelProfile.minDimension,
996-
]}
997-
onValueChange={(values) =>
998-
updateSetting(
999-
"codebaseIndexEmbedderModelDimension",
1000-
values[0],
1001-
)
1002-
}
1003-
className="flex-1"
1004-
data-testid="model-dimension-slider"
1005-
/>
1006-
<span className="w-12 text-center">
1007-
{currentSettings.codebaseIndexEmbedderModelDimension ??
1008-
selectedModelProfile.defaultDimension ??
1009-
selectedModelProfile.minDimension}
1010-
</span>
1011-
<VSCodeButton
1012-
appearance="icon"
1013-
title={t("settings:codeIndex.resetToDefault")}
1014-
onClick={() =>
1015-
updateSetting(
1016-
"codebaseIndexEmbedderModelDimension",
1017-
selectedModelProfile.defaultDimension,
1018-
)
1019-
}>
1020-
<span className="codicon codicon-discard" />
1021-
</VSCodeButton>
1022-
</div>
997+
<label htmlFor="gemini-dimension" className="text-sm">
998+
{t("settings:codeIndex.modelDimensionLabel")}{" "}
999+
{t("settings:codeIndex.dimensionRange", {
1000+
min: selectedModelProfile.minDimension,
1001+
max: selectedModelProfile.maxDimension,
1002+
})}
1003+
</label>
1004+
<VSCodeTextField
1005+
id="gemini-dimension"
1006+
value={
1007+
currentSettings.codebaseIndexEmbedderModelDimension?.toString() ||
1008+
""
1009+
}
1010+
onInput={(e: any) =>
1011+
updateSetting(
1012+
"codebaseIndexEmbedderModelDimension",
1013+
e.target.value
1014+
? parseInt(e.target.value, 10)
1015+
: undefined,
1016+
)
1017+
}
1018+
className="w-full"
1019+
/>
10231020
{formErrors.codebaseIndexEmbedderModelDimension && (
10241021
<p className="text-xs text-vscode-errorForeground mt-1 mb-0">
10251022
{formErrors.codebaseIndexEmbedderModelDimension}

webview-ui/src/i18n/locales/en/settings.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
"qdrantUrlPlaceholder": "http://localhost:6333",
9696
"saveError": "Failed to save settings",
9797
"modelDimensions": "({{dimension}} dimensions)",
98+
"dimensionRange": "({{min}}-{{max}})",
9899
"saveSuccess": "Settings saved successfully",
99100
"saving": "Saving...",
100101
"saveSettings": "Save",
@@ -115,6 +116,7 @@
115116
"apiKeyRequired": "API key is required",
116117
"modelIdRequired": "Model ID is required",
117118
"modelDimensionRequired": "Model dimension is required",
119+
"invalidDimension": "Dimension must be between {{min}} and {{max}}",
118120
"geminiApiKeyRequired": "Gemini API key is required",
119121
"ollamaBaseUrlRequired": "Ollama base URL is required",
120122
"baseUrlRequired": "Base URL is required",

0 commit comments

Comments
 (0)