1- import { Plus , RefreshCw , X } from "lucide-react" ;
2- import { useState } from "react" ;
1+ import { RefreshCw } from "lucide-react" ;
32import { useModels } from "../hooks/useModels" ;
43import type { AppSettings , LLMProvider } from "../types" ;
54import { PROVIDERS } from "../utils/providers" ;
6- import Button from "./ui/Button" ;
7- import Input from "./ui/Input" ;
85import Select from "./ui/Select" ;
96
107interface ModelSelectorProps {
@@ -20,48 +17,21 @@ export default function ModelSelector({
2017 selectedModel,
2118 settings,
2219 onModelChange,
23- onSettingsChange : _onSettingsChange ,
20+ onSettingsChange,
2421} : ModelSelectorProps ) {
25- const {
26- models,
27- isLoading,
28- error,
29- refreshModels,
30- addCustomModel,
31- removeCustomModel,
32- } = useModels ( provider , settings ) ;
33- const [ showCustomInput , setShowCustomInput ] = useState ( false ) ;
34- const [ customModelInput , setCustomModelInput ] = useState ( "" ) ;
22+ const { models, isLoading, error, refreshModels } = useModels (
23+ provider ,
24+ settings ,
25+ onSettingsChange ,
26+ ) ;
3527
3628 const modelOptions = models . map ( ( model ) => ( {
3729 value : model ,
3830 label : model ,
3931 } ) ) ;
4032
41- const handleAddCustomModel = async ( ) => {
42- if ( ! customModelInput . trim ( ) ) return ;
43-
44- await addCustomModel ( customModelInput . trim ( ) ) ;
45- onModelChange ( customModelInput . trim ( ) ) ;
46- setCustomModelInput ( "" ) ;
47- setShowCustomInput ( false ) ;
48- } ;
49-
50- const handleRemoveCustomModel = async ( model : string ) => {
51- await removeCustomModel ( model ) ;
52- if ( selectedModel === model && models . length > 0 ) {
53- onModelChange ( models [ 0 ] ) ;
54- }
55- } ;
56-
57- const isCustomModel = ( model : string ) => {
58- const customModels = settings . customModels ?. [ provider ] || [ ] ;
59- return customModels . includes ( model ) ;
60- } ;
61-
6233 const providerInfo = PROVIDERS [ provider ] ;
6334 const showRefreshButton = providerInfo ?. supportsModelRefresh ;
64- const showAddCustomButton = providerInfo ?. supportsCustomModels ;
6535
6636 return (
6737 < div className = "space-y-3" >
@@ -88,16 +58,6 @@ export default function ModelSelector({
8858 />
8959 </ button >
9060 ) }
91- { showAddCustomButton && (
92- < button
93- type = "button"
94- onClick = { ( ) => setShowCustomInput ( ! showCustomInput ) }
95- className = "p-1 text-gray-400 hover:text-gray-600"
96- title = "Add custom model"
97- >
98- < Plus className = "w-4 h-4" />
99- </ button >
100- ) }
10161 </ div >
10262 </ div >
10363
@@ -111,80 +71,18 @@ export default function ModelSelector({
11171 < Select
11272 options = { modelOptions }
11373 value = { selectedModel }
114- onChange = { onModelChange }
74+ onChange = { ( model ) => {
75+ onModelChange ( model ) ;
76+ onSettingsChange ( { model } ) ;
77+ } }
11578 disabled = { isLoading }
11679 placeholder = { isLoading ? "Loading models..." : "Select a model" }
11780 />
118-
119- { showAddCustomButton && showCustomInput && (
120- < div className = "flex gap-2" >
121- < Input
122- label = ""
123- value = { customModelInput }
124- onChange = { ( e ) => setCustomModelInput ( e . target . value ) }
125- placeholder = "Enter custom model name (e.g., llama3.2:7b)"
126- onKeyDown = { ( e ) => {
127- if ( e . key === "Enter" ) {
128- e . preventDefault ( ) ;
129- handleAddCustomModel ( ) ;
130- }
131- if ( e . key === "Escape" ) {
132- setShowCustomInput ( false ) ;
133- setCustomModelInput ( "" ) ;
134- }
135- } }
136- />
137- < Button
138- onClick = { handleAddCustomModel }
139- disabled = { ! customModelInput . trim ( ) }
140- size = "sm"
141- >
142- Add
143- </ Button >
144- < Button
145- onClick = { ( ) => {
146- setShowCustomInput ( false ) ;
147- setCustomModelInput ( "" ) ;
148- } }
149- variant = "outline"
150- size = "sm"
151- >
152- Cancel
153- </ Button >
154- </ div >
155- ) }
15681 </ div >
15782
158- { /* Show custom models with remove option - only for providers that support custom models */ }
159- { showAddCustomButton && models . some ( ( model ) => isCustomModel ( model ) ) && (
160- < div className = "space-y-1" >
161- < div className = "text-xs text-gray-500" > Custom Models:</ div >
162- < div className = "flex flex-wrap gap-1" >
163- { models
164- . filter ( ( model ) => isCustomModel ( model ) )
165- . map ( ( model ) => (
166- < div
167- key = { model }
168- className = "flex items-center gap-1 bg-blue-50 text-blue-700 px-2 py-1 rounded text-xs"
169- >
170- < span > { model } </ span >
171- < button
172- type = "button"
173- onClick = { ( ) => handleRemoveCustomModel ( model ) }
174- className = "text-blue-500 hover:text-blue-700"
175- title = "Remove custom model"
176- >
177- < X className = "w-3 h-3" />
178- </ button >
179- </ div >
180- ) ) }
181- </ div >
182- </ div >
183- ) }
184-
18583 { models . length === 0 && ! isLoading && (
18684 < div className = "text-xs text-gray-500 bg-gray-50 p-2 rounded" >
187- No models available. Try refreshing or add a custom model .
85+ No models available. Try refreshing the list .
18886 </ div >
18987 ) }
19088 </ div >
0 commit comments