jan/web-app/src/hooks/useLlamacppDevices.ts
Dinh Long Nguyen a30eb7f968
feat: Jan Web (reusing Jan Desktop UI) (#6298)
* add platform guards

* add service management

* fix types

* move to zustand for servicehub

* update App Updater

* update tauri missing move

* update app updater

* refactor: move PlatformFeatures to separate const file

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* change tauri fetch name

* update implementation

* update extension fetch

* make web version run properly

* disabled unused web settings

* fix all tests

* fix lint

* fix tests

* add mock for extension

* fix build

* update make and mise

* fix tsconfig for web-extensions

* fix loader type

* cleanup

* fix test

* update error handling + mcp should be working

* Update mcp init

* use separate is_web_app build property

* Remove fixed model catalog url

* fix additional tests

* fix download issue (event emitter not implemented correctly)

* Update Title html

* fix app logs

* update root tsx render timing

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-09-05 01:47:46 +07:00

103 lines
3.2 KiB
TypeScript

import { create } from 'zustand'
import { getServiceHub } from '@/hooks/useServiceHub'
import type { DeviceList } from '@/services/hardware/types'
import { useModelProvider } from './useModelProvider'
interface LlamacppDevicesStore {
devices: (DeviceList & { activated: boolean })[]
loading: boolean
error: string | null
// Actions
fetchDevices: () => Promise<void>
clearError: () => void
setDevices: (devices: (DeviceList & { activated: boolean })[]) => void
toggleDevice: (deviceId: string) => void
}
export const useLlamacppDevices = create<LlamacppDevicesStore>((set, get) => ({
devices: [],
loading: false,
error: null,
fetchDevices: async () => {
set({ loading: true, error: null })
try {
const devices = await getServiceHub().hardware().getLlamacppDevices()
// Check current device setting from provider
const { getProviderByName } = useModelProvider.getState()
const llamacppProvider = getProviderByName('llamacpp')
const currentDeviceSetting = llamacppProvider?.settings.find(
(s) => s.key === 'device'
)?.controller_props.value as string
// Parse device setting from extension which represents activated devices
const activatedDevices = currentDeviceSetting
? currentDeviceSetting.split(',').map(d => d.trim()).filter(Boolean)
: []
const devicesWithActivation = devices.map((device) => ({
...device,
activated:
// Empty device setting means all devices are activated
!currentDeviceSetting || currentDeviceSetting === '' || activatedDevices.includes(device.id),
}))
set({ devices: devicesWithActivation, loading: false })
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : 'Failed to fetch devices'
set({ error: errorMessage, loading: false })
}
},
clearError: () => set({ error: null }),
setDevices: (devices) => set({ devices }),
toggleDevice: async (deviceId: string) => {
// Toggle device activation in the local state
set((state) => ({
devices: state.devices.map((device) =>
device.id === deviceId
? { ...device, activated: !device.activated }
: device
),
}))
// Update llamacpp provider settings
const { getProviderByName, updateProvider } = useModelProvider.getState()
const llamacppProvider = getProviderByName('llamacpp')
if (llamacppProvider) {
// Get activated devices after toggle
const activatedDeviceIds = get().devices
.filter((device) => device.activated)
.map((device) => device.id)
const deviceString = activatedDeviceIds.join(',')
const updatedSettings = llamacppProvider.settings.map((setting) => {
if (setting.key === 'device') {
return {
...setting,
controller_props: {
...setting.controller_props,
value: deviceString.length > 0 ? deviceString : 'none',
},
}
}
return setting
})
await getServiceHub().providers().updateSettings('llamacpp', updatedSettings)
updateProvider('llamacpp', {
settings: updatedSettings,
})
}
},
}))