Skip to content

Commit eff72ee

Browse files
committed
fix: config-manager
1 parent 2ba64d6 commit eff72ee

File tree

5 files changed

+71
-32
lines changed

5 files changed

+71
-32
lines changed

webview-ui/src/components/settings/ApiOptions.tsx

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,14 @@ interface ApiOptionsProps {
4545
}
4646

4747
const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) => {
48-
const { apiConfiguration, setApiConfiguration, uriScheme, onUpdateApiConfig } = useExtensionState()
48+
const { apiConfiguration, setApiConfiguration, uriScheme, handleInputChange } = useExtensionState()
4949
const [ollamaModels, setOllamaModels] = useState<string[]>([])
5050
const [lmStudioModels, setLmStudioModels] = useState<string[]>([])
5151
const [vsCodeLmModels, setVsCodeLmModels] = useState<vscodemodels.LanguageModelChatSelector[]>([])
5252
const [anthropicBaseUrlSelected, setAnthropicBaseUrlSelected] = useState(!!apiConfiguration?.anthropicBaseUrl)
5353
const [azureApiVersionSelected, setAzureApiVersionSelected] = useState(!!apiConfiguration?.azureApiVersion)
5454
const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false)
5555

56-
const handleInputChange = (field: keyof ApiConfiguration) => (event: any) => {
57-
const apiConfig = { ...apiConfiguration, [field]: event.target.value }
58-
onUpdateApiConfig(apiConfig)
59-
// setApiConfiguration(apiConfig)
60-
}
61-
6256
const { selectedProvider, selectedModelId, selectedModelInfo } = useMemo(() => {
6357
return normalizeApiConfiguration(apiConfiguration)
6458
}, [apiConfiguration])
@@ -162,7 +156,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
162156
value={apiConfiguration?.apiKey || ""}
163157
style={{ width: "100%" }}
164158
type="password"
165-
onInput={handleInputChange("apiKey")}
159+
onChange={handleInputChange("apiKey")}
166160
placeholder="Enter API Key...">
167161
<span style={{ fontWeight: 500 }}>Anthropic API Key</span>
168162
</VSCodeTextField>
@@ -183,7 +177,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
183177
value={apiConfiguration?.anthropicBaseUrl || ""}
184178
style={{ width: "100%", marginTop: 3 }}
185179
type="url"
186-
onInput={handleInputChange("anthropicBaseUrl")}
180+
onChange={handleInputChange("anthropicBaseUrl")}
187181
placeholder="Default: https://api.anthropic.com"
188182
/>
189183
)}
@@ -212,7 +206,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
212206
value={apiConfiguration?.glamaApiKey || ""}
213207
style={{ width: "100%" }}
214208
type="password"
215-
onInput={handleInputChange("glamaApiKey")}
209+
onChange={handleInputChange("glamaApiKey")}
216210
placeholder="Enter API Key...">
217211
<span style={{ fontWeight: 500 }}>Glama API Key</span>
218212
</VSCodeTextField>
@@ -241,7 +235,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
241235
value={apiConfiguration?.openAiNativeApiKey || ""}
242236
style={{ width: "100%" }}
243237
type="password"
244-
onInput={handleInputChange("openAiNativeApiKey")}
238+
onChange={handleInputChange("openAiNativeApiKey")}
245239
placeholder="Enter API Key...">
246240
<span style={{ fontWeight: 500 }}>OpenAI API Key</span>
247241
</VSCodeTextField>
@@ -269,7 +263,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
269263
value={apiConfiguration?.mistralApiKey || ""}
270264
style={{ width: "100%" }}
271265
type="password"
272-
onInput={handleInputChange("mistralApiKey")}
266+
onChange={handleInputChange("mistralApiKey")}
273267
placeholder="Enter API Key...">
274268
<span style={{ fontWeight: 500 }}>Mistral API Key</span>
275269
</VSCodeTextField>
@@ -300,7 +294,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
300294
value={apiConfiguration?.openRouterApiKey || ""}
301295
style={{ width: "100%" }}
302296
type="password"
303-
onInput={handleInputChange("openRouterApiKey")}
297+
onChange={handleInputChange("openRouterApiKey")}
304298
placeholder="Enter API Key...">
305299
<span style={{ fontWeight: 500 }}>OpenRouter API Key</span>
306300
</VSCodeTextField>
@@ -346,23 +340,23 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
346340
value={apiConfiguration?.awsAccessKey || ""}
347341
style={{ width: "100%" }}
348342
type="password"
349-
onInput={handleInputChange("awsAccessKey")}
343+
onChange={handleInputChange("awsAccessKey")}
350344
placeholder="Enter Access Key...">
351345
<span style={{ fontWeight: 500 }}>AWS Access Key</span>
352346
</VSCodeTextField>
353347
<VSCodeTextField
354348
value={apiConfiguration?.awsSecretKey || ""}
355349
style={{ width: "100%" }}
356350
type="password"
357-
onInput={handleInputChange("awsSecretKey")}
351+
onChange={handleInputChange("awsSecretKey")}
358352
placeholder="Enter Secret Key...">
359353
<span style={{ fontWeight: 500 }}>AWS Secret Key</span>
360354
</VSCodeTextField>
361355
<VSCodeTextField
362356
value={apiConfiguration?.awsSessionToken || ""}
363357
style={{ width: "100%" }}
364358
type="password"
365-
onInput={handleInputChange("awsSessionToken")}
359+
onChange={handleInputChange("awsSessionToken")}
366360
placeholder="Enter Session Token...">
367361
<span style={{ fontWeight: 500 }}>AWS Session Token</span>
368362
</VSCodeTextField>
@@ -428,7 +422,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
428422
<VSCodeTextField
429423
value={apiConfiguration?.vertexProjectId || ""}
430424
style={{ width: "100%" }}
431-
onInput={handleInputChange("vertexProjectId")}
425+
onChange={handleInputChange("vertexProjectId")}
432426
placeholder="Enter Project ID...">
433427
<span style={{ fontWeight: 500 }}>Google Cloud Project ID</span>
434428
</VSCodeTextField>
@@ -486,7 +480,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
486480
value={apiConfiguration?.geminiApiKey || ""}
487481
style={{ width: "100%" }}
488482
type="password"
489-
onInput={handleInputChange("geminiApiKey")}
483+
onChange={handleInputChange("geminiApiKey")}
490484
placeholder="Enter API Key...">
491485
<span style={{ fontWeight: 500 }}>Gemini API Key</span>
492486
</VSCodeTextField>
@@ -514,15 +508,15 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
514508
value={apiConfiguration?.openAiBaseUrl || ""}
515509
style={{ width: "100%" }}
516510
type="url"
517-
onInput={handleInputChange("openAiBaseUrl")}
511+
onChange={handleInputChange("openAiBaseUrl")}
518512
placeholder={"Enter base URL..."}>
519513
<span style={{ fontWeight: 500 }}>Base URL</span>
520514
</VSCodeTextField>
521515
<VSCodeTextField
522516
value={apiConfiguration?.openAiApiKey || ""}
523517
style={{ width: "100%" }}
524518
type="password"
525-
onInput={handleInputChange("openAiApiKey")}
519+
onChange={handleInputChange("openAiApiKey")}
526520
placeholder="Enter API Key...">
527521
<span style={{ fontWeight: 500 }}>API Key</span>
528522
</VSCodeTextField>
@@ -552,7 +546,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
552546
<VSCodeTextField
553547
value={apiConfiguration?.azureApiVersion || ""}
554548
style={{ width: "100%", marginTop: 3 }}
555-
onInput={handleInputChange("azureApiVersion")}
549+
onChange={handleInputChange("azureApiVersion")}
556550
placeholder={`Default: ${azureOpenAiDefaultApiVersion}`}
557551
/>
558552
)}
@@ -576,14 +570,14 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
576570
value={apiConfiguration?.lmStudioBaseUrl || ""}
577571
style={{ width: "100%" }}
578572
type="url"
579-
onInput={handleInputChange("lmStudioBaseUrl")}
573+
onChange={handleInputChange("lmStudioBaseUrl")}
580574
placeholder={"Default: http://localhost:1234"}>
581575
<span style={{ fontWeight: 500 }}>Base URL (optional)</span>
582576
</VSCodeTextField>
583577
<VSCodeTextField
584578
value={apiConfiguration?.lmStudioModelId || ""}
585579
style={{ width: "100%" }}
586-
onInput={handleInputChange("lmStudioModelId")}
580+
onChange={handleInputChange("lmStudioModelId")}
587581
placeholder={"e.g. meta-llama-3.1-8b-instruct"}>
588582
<span style={{ fontWeight: 500 }}>Model ID</span>
589583
</VSCodeTextField>
@@ -645,7 +639,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
645639
value={apiConfiguration?.deepSeekApiKey || ""}
646640
style={{ width: "100%" }}
647641
type="password"
648-
onInput={handleInputChange("deepSeekApiKey")}
642+
onChange={handleInputChange("deepSeekApiKey")}
649643
placeholder="Enter API Key...">
650644
<span style={{ fontWeight: 500 }}>DeepSeek API Key</span>
651645
</VSCodeTextField>
@@ -735,14 +729,14 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
735729
value={apiConfiguration?.ollamaBaseUrl || ""}
736730
style={{ width: "100%" }}
737731
type="url"
738-
onInput={handleInputChange("ollamaBaseUrl")}
732+
onChange={handleInputChange("ollamaBaseUrl")}
739733
placeholder={"Default: http://localhost:11434"}>
740734
<span style={{ fontWeight: 500 }}>Base URL (optional)</span>
741735
</VSCodeTextField>
742736
<VSCodeTextField
743737
value={apiConfiguration?.ollamaModelId || ""}
744738
style={{ width: "100%" }}
745-
onInput={handleInputChange("ollamaModelId")}
739+
onChange={handleInputChange("ollamaModelId")}
746740
placeholder={"e.g. llama3.1"}>
747741
<span style={{ fontWeight: 500 }}>Model ID</span>
748742
</VSCodeTextField>

webview-ui/src/components/settings/GlamaModelPicker.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,18 @@ const GlamaModelPicker: React.FC = () => {
167167
placeholder="Search and select a model..."
168168
value={searchTerm}
169169
onInput={(e) => {
170-
handleModelChange((e.target as HTMLInputElement)?.value?.toLowerCase())
170+
const newModelId = (e.target as HTMLInputElement)?.value?.toLowerCase()
171+
const apiConfig = {
172+
...apiConfiguration,
173+
openAiModelId: newModelId,
174+
}
175+
setApiConfiguration(apiConfig)
176+
setSearchTerm(newModelId)
171177
setIsDropdownVisible(true)
172178
}}
179+
onChange={(e) => {
180+
handleModelChange((e.target as HTMLInputElement)?.value?.toLowerCase())
181+
}}
173182
onFocus={() => setIsDropdownVisible(true)}
174183
onKeyDown={handleKeyDown}
175184
style={{ width: "100%", zIndex: GLAMA_MODEL_PICKER_Z_INDEX, position: "relative" }}>

webview-ui/src/components/settings/OpenAiModelPicker.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ const OpenAiModelPicker: React.FC = () => {
2525
}
2626
setApiConfiguration(apiConfig)
2727
onUpdateApiConfig(apiConfig)
28-
29-
setSearchTerm(newModelId)
3028
}
3129

3230
useEffect(() => {
@@ -161,9 +159,18 @@ const OpenAiModelPicker: React.FC = () => {
161159
placeholder="Search and select a model..."
162160
value={searchTerm}
163161
onInput={(e) => {
164-
handleModelChange((e.target as HTMLInputElement)?.value?.toLowerCase())
162+
const newModelId = (e.target as HTMLInputElement)?.value?.toLowerCase()
163+
const apiConfig = {
164+
...apiConfiguration,
165+
openAiModelId: newModelId,
166+
}
167+
setApiConfiguration(apiConfig)
168+
setSearchTerm(newModelId)
165169
setIsDropdownVisible(true)
166170
}}
171+
onChange={(e) => {
172+
handleModelChange((e.target as HTMLInputElement)?.value?.toLowerCase())
173+
}}
167174
onFocus={() => setIsDropdownVisible(true)}
168175
onKeyDown={handleKeyDown}
169176
style={{ width: "100%", zIndex: OPENAI_MODEL_PICKER_Z_INDEX, position: "relative" }}>

webview-ui/src/components/settings/OpenRouterModelPicker.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,18 @@ const OpenRouterModelPicker: React.FC = () => {
167167
placeholder="Search and select a model..."
168168
value={searchTerm}
169169
onInput={(e) => {
170-
handleModelChange((e.target as HTMLInputElement)?.value?.toLowerCase())
170+
const newModelId = (e.target as HTMLInputElement)?.value?.toLowerCase()
171+
const apiConfig = {
172+
...apiConfiguration,
173+
openAiModelId: newModelId,
174+
}
175+
setApiConfiguration(apiConfig)
176+
setSearchTerm(newModelId)
171177
setIsDropdownVisible(true)
172178
}}
179+
onChange={(e) => {
180+
handleModelChange((e.target as HTMLInputElement)?.value?.toLowerCase())
181+
}}
173182
onFocus={() => setIsDropdownVisible(true)}
174183
onKeyDown={handleKeyDown}
175184
style={{ width: "100%", zIndex: OPENROUTER_MODEL_PICKER_Z_INDEX, position: "relative" }}>

webview-ui/src/context/ExtensionStateContext.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export interface ExtensionStateContextType extends ExtensionState {
6565
setExperimentalDiffStrategy: (value: boolean) => void
6666
autoApprovalEnabled?: boolean
6767
setAutoApprovalEnabled: (value: boolean) => void
68+
handleInputChange: (field: keyof ApiConfiguration) => (event: any) => void
6869
}
6970

7071
export const ExtensionStateContext = createContext<ExtensionStateContextType | undefined>(undefined)
@@ -117,15 +118,33 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
117118

118119
const onUpdateApiConfig = useCallback((apiConfig: ApiConfiguration) => {
119120
setState((currentState) => {
121+
console.log("onUpdateApiConfig", currentState, apiConfig)
122+
120123
vscode.postMessage({
121124
type: "upsertApiConfiguration",
122-
text: currentState.currentApiConfigName, // Access latest state
125+
text: currentState.currentApiConfigName,
123126
apiConfiguration: apiConfig,
124127
})
125128
return currentState // No state update needed
126129
})
127130
}, [])
128131

132+
const handleInputChange = useCallback(
133+
(field: keyof ApiConfiguration) => (event: any) => {
134+
setState((currentState) => {
135+
console.log("handleInputChange", currentState, event)
136+
137+
vscode.postMessage({
138+
type: "upsertApiConfiguration",
139+
text: currentState.currentApiConfigName,
140+
apiConfiguration: { ...currentState.apiConfiguration, [field]: event.target.value },
141+
})
142+
return currentState // No state update needed
143+
})
144+
},
145+
[],
146+
)
147+
129148
const handleMessage = useCallback(
130149
(event: MessageEvent) => {
131150
const message: ExtensionMessage = event.data
@@ -258,6 +277,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
258277
setExperimentalDiffStrategy: (value) =>
259278
setState((prevState) => ({ ...prevState, experimentalDiffStrategy: value })),
260279
setAutoApprovalEnabled: (value) => setState((prevState) => ({ ...prevState, autoApprovalEnabled: value })),
280+
handleInputChange,
261281
}
262282

263283
return <ExtensionStateContext.Provider value={contextValue}>{children}</ExtensionStateContext.Provider>

0 commit comments

Comments
 (0)