Skip to content

Commit 01ada08

Browse files
committed
fix: add loader version backend llamacpp
1 parent 5603794 commit 01ada08

File tree

2 files changed

+127
-92
lines changed

2 files changed

+127
-92
lines changed

extensions/llamacpp-extension/settings.json

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,6 @@
5959
"textAlign": "right"
6060
}
6161
},
62-
{
63-
"key": "ctx_size",
64-
"title": "Context Size",
65-
"description": "Size of the prompt context (0 = loaded from model).",
66-
"controllerType": "input",
67-
"controllerProps": {
68-
"value": 8192,
69-
"placeholder": "8192",
70-
"type": "number",
71-
"textAlign": "right"
72-
}
73-
},
7462
{
7563
"key": "context_shift",
7664
"title": "Context Shift",
@@ -116,18 +104,6 @@
116104
"textAlign": "right"
117105
}
118106
},
119-
{
120-
"key": "n_gpu_layers",
121-
"title": "GPU Layers",
122-
"description": "Number of model layers to offload to the GPU (-1 for all layers, 0 for CPU only).",
123-
"controllerType": "input",
124-
"controllerProps": {
125-
"value": -1,
126-
"placeholder": "-1",
127-
"type": "number",
128-
"textAlign": "right"
129-
}
130-
},
131107
{
132108
"key": "device",
133109
"title": "Devices for Offload",

web-app/src/routes/settings/providers/$providerName.tsx

Lines changed: 127 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable react-hooks/exhaustive-deps */
12
import { Card, CardItem } from '@/containers/Card'
23
import HeaderPage from '@/containers/HeaderPage'
34
import SettingsMenu from '@/containers/SettingsMenu'
@@ -84,6 +85,17 @@ function ProviderDetail() {
8485
const isSetup = step === 'setup_remote_provider'
8586
const navigate = useNavigate()
8687

88+
// Check if llamacpp provider needs backend configuration
89+
const needsBackendConfig =
90+
provider?.provider === 'llamacpp' &&
91+
provider.settings?.some(
92+
(setting) =>
93+
setting.key === 'version_backend' &&
94+
(setting.controller_props.value === 'none' ||
95+
setting.controller_props.value === '' ||
96+
!setting.controller_props.value)
97+
)
98+
8799
useEffect(() => {
88100
// Initial data fetch
89101
getActiveModels().then((models) => setActiveModels(models || []))
@@ -96,6 +108,44 @@ function ProviderDetail() {
96108
return () => clearInterval(intervalId)
97109
}, [setActiveModels])
98110

111+
// Auto-refresh provider settings to get updated backend configuration
112+
const refreshSettings = async () => {
113+
if (!provider) return
114+
115+
try {
116+
// Refresh providers to get updated settings from the extension
117+
const updatedProviders = await getProviders()
118+
setProviders(updatedProviders)
119+
} catch (error) {
120+
console.error('Failed to refresh settings:', error)
121+
}
122+
}
123+
124+
// Auto-refresh settings when provider changes or when llamacpp needs backend config
125+
useEffect(() => {
126+
if (provider && needsBackendConfig) {
127+
// Auto-refresh every 3 seconds when backend is being configured
128+
const intervalId = setInterval(refreshSettings, 3000)
129+
return () => clearInterval(intervalId)
130+
}
131+
}, [provider, needsBackendConfig])
132+
133+
// Auto-refresh models for non-predefined providers
134+
useEffect(() => {
135+
if (
136+
provider &&
137+
provider.provider !== 'llamacpp' &&
138+
!predefinedProviders.some((p) => p.provider === provider.provider) &&
139+
provider.base_url
140+
) {
141+
// Auto-refresh models every 10 seconds for remote providers
142+
const intervalId = setInterval(() => {
143+
handleRefreshModels()
144+
}, 10000)
145+
return () => clearInterval(intervalId)
146+
}
147+
}, [provider])
148+
99149
const handleJoyrideCallback = (data: CallBackProps) => {
100150
const { status } = data
101151

@@ -250,81 +300,90 @@ function ProviderDetail() {
250300
// Use the DynamicController component
251301
const actionComponent = (
252302
<div className="mt-2">
253-
<DynamicControllerSetting
254-
controllerType={setting.controller_type}
255-
controllerProps={setting.controller_props}
256-
className={cn(
257-
setting.key === 'api-key' &&
258-
'third-step-setup-remote-provider',
259-
setting.key === 'device' && 'hidden'
260-
)}
261-
onChange={(newValue) => {
262-
if (provider) {
263-
const newSettings = [...provider.settings]
264-
// Handle different value types by forcing the type
265-
// Use type assertion to bypass type checking
266-
267-
;(
268-
newSettings[settingIndex].controller_props as {
269-
value: string | boolean | number
270-
}
271-
).value = newValue
272-
273-
// Create update object with updated settings
274-
const updateObj: Partial<ModelProvider> = {
275-
settings: newSettings,
276-
}
277-
// Check if this is an API key or base URL setting and update the corresponding top-level field
278-
const settingKey = setting.key
279-
if (
280-
settingKey === 'api-key' &&
281-
typeof newValue === 'string'
282-
) {
283-
updateObj.api_key = newValue
284-
} else if (
285-
settingKey === 'base-url' &&
286-
typeof newValue === 'string'
287-
) {
288-
updateObj.base_url = newValue
289-
}
303+
{needsBackendConfig &&
304+
setting.key === 'version_backend' ? (
305+
<div className="flex items-center gap-1 text-sm text-main-view-fg/70">
306+
<IconLoader size={16} className="animate-spin" />
307+
<span>loading</span>
308+
</div>
309+
) : (
310+
<DynamicControllerSetting
311+
controllerType={setting.controller_type}
312+
controllerProps={setting.controller_props}
313+
className={cn(
314+
setting.key === 'api-key' &&
315+
'third-step-setup-remote-provider',
316+
setting.key === 'device' && 'hidden'
317+
)}
318+
onChange={(newValue) => {
319+
if (provider) {
320+
const newSettings = [...provider.settings]
321+
// Handle different value types by forcing the type
322+
// Use type assertion to bypass type checking
290323

291-
// Reset device setting to empty when backend version changes
292-
if (settingKey === 'version_backend') {
293-
const deviceSettingIndex =
294-
newSettings.findIndex(
295-
(s) => s.key === 'device'
296-
)
324+
;(
325+
newSettings[settingIndex]
326+
.controller_props as {
327+
value: string | boolean | number
328+
}
329+
).value = newValue
297330

298-
if (deviceSettingIndex !== -1) {
299-
;(
300-
newSettings[deviceSettingIndex]
301-
.controller_props as {
302-
value: string
303-
}
304-
).value = ''
331+
// Create update object with updated settings
332+
const updateObj: Partial<ModelProvider> = {
333+
settings: newSettings,
305334
}
335+
// Check if this is an API key or base URL setting and update the corresponding top-level field
336+
const settingKey = setting.key
337+
if (
338+
settingKey === 'api-key' &&
339+
typeof newValue === 'string'
340+
) {
341+
updateObj.api_key = newValue
342+
} else if (
343+
settingKey === 'base-url' &&
344+
typeof newValue === 'string'
345+
) {
346+
updateObj.base_url = newValue
347+
}
348+
349+
// Reset device setting to empty when backend version changes
350+
if (settingKey === 'version_backend') {
351+
const deviceSettingIndex =
352+
newSettings.findIndex(
353+
(s) => s.key === 'device'
354+
)
306355

307-
// Reset llamacpp device activations when backend version changes
308-
if (providerName === 'llamacpp') {
309-
const { setActivatedDevices } =
310-
useLlamacppDevices.getState()
311-
setActivatedDevices([])
356+
if (deviceSettingIndex !== -1) {
357+
;(
358+
newSettings[deviceSettingIndex]
359+
.controller_props as {
360+
value: string
361+
}
362+
).value = ''
363+
}
364+
365+
// Reset llamacpp device activations when backend version changes
366+
if (providerName === 'llamacpp') {
367+
const { setActivatedDevices } =
368+
useLlamacppDevices.getState()
369+
setActivatedDevices([])
370+
}
312371
}
313-
}
314372

315-
updateSettings(
316-
providerName,
317-
updateObj.settings ?? []
318-
)
319-
updateProvider(providerName, {
320-
...provider,
321-
...updateObj,
322-
})
373+
updateSettings(
374+
providerName,
375+
updateObj.settings ?? []
376+
)
377+
updateProvider(providerName, {
378+
...provider,
379+
...updateObj,
380+
})
323381

324-
stopAllModels()
325-
}
326-
}}
327-
/>
382+
stopAllModels()
383+
}
384+
}}
385+
/>
386+
)}
328387
</div>
329388
)
330389

0 commit comments

Comments
 (0)