Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 20 additions & 22 deletions web-app/src/containers/DropdownModelProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,25 @@

// Helper functions for localStorage
const getLastUsedModel = (): { provider: string; model: string } | null => {
try {
const stored = localStorage.getItem(localStorageKey.lastUsedModel)
return stored ? JSON.parse(stored) : null
} catch (error) {
console.debug('Failed to get last used model from localStorage:', error)
return null
}
}

Check warning on line 45 in web-app/src/containers/DropdownModelProvider.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

38-45 lines are not covered with tests

const setLastUsedModel = (provider: string, model: string) => {
try {
localStorage.setItem(
localStorageKey.lastUsedModel,
JSON.stringify({ provider, model })
)
} catch (error) {
console.debug('Failed to set last used model in localStorage:', error)
}
}

Check warning on line 56 in web-app/src/containers/DropdownModelProvider.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

48-56 lines are not covered with tests

const DropdownModelProvider = ({
model,
Expand All @@ -78,43 +78,39 @@
const [searchValue, setSearchValue] = useState('')
const searchInputRef = useRef<HTMLInputElement>(null)

// Helper function to check if a model exists in providers
const checkModelExists = useCallback((providerName: string, modelId: string) => {
const provider = providers.find(
(p) => p.provider === providerName && p.active
)
return provider?.models.find((m) => m.id === modelId)

Check warning on line 86 in web-app/src/containers/DropdownModelProvider.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

83-86 lines are not covered with tests
}, [providers])

// Initialize model provider only once
useEffect(() => {
// Auto select model when existing thread is passed
if (model) {
selectModelProvider(model?.provider as string, model?.id as string)
if (!checkModelExists(model.provider, model.id)) {
selectModelProvider('', '')
}

Check warning on line 96 in web-app/src/containers/DropdownModelProvider.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

93-96 lines are not covered with tests
} else if (useLastUsedModel) {
// Try to use last used model only when explicitly requested (for new chat)
const lastUsed = getLastUsedModel()
if (lastUsed) {
// Verify the last used model still exists
const provider = providers.find(
(p) => p.provider === lastUsed.provider && p.active
)
const modelExists = provider?.models.find(
(m) => m.id === lastUsed.model
)

if (provider && modelExists) {
selectModelProvider(lastUsed.provider, lastUsed.model)
} else {
// Fallback to default model if last used model no longer exists
selectModelProvider('llamacpp', 'llama3.2:3b')
}
if (lastUsed && checkModelExists(lastUsed.provider, lastUsed.model)) {
selectModelProvider(lastUsed.provider, lastUsed.model)
} else {

Check warning on line 102 in web-app/src/containers/DropdownModelProvider.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

99-102 lines are not covered with tests
// default model, we should add from setting
selectModelProvider('llamacpp', 'llama3.2:3b')
// Fallback to default model if last used model no longer exists
selectModelProvider('', '')
}
} else {
// default model for non-new-chat contexts
selectModelProvider('llamacpp', 'llama3.2:3b')
}

Check warning on line 106 in web-app/src/containers/DropdownModelProvider.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

104-106 lines are not covered with tests
}, [
model,
selectModelProvider,
updateCurrentThreadModel,
providers,
useLastUsedModel,
checkModelExists,
])

// Update display model when selection changes
Expand All @@ -128,21 +124,21 @@

// Reset search value when dropdown closes
const onOpenChange = useCallback((open: boolean) => {
setOpen(open)
if (!open) {
requestAnimationFrame(() => setSearchValue(''))
} else {

Check warning on line 130 in web-app/src/containers/DropdownModelProvider.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

127-130 lines are not covered with tests
// Focus search input when opening
setTimeout(() => {
searchInputRef.current?.focus()
}, 100)
}

Check warning on line 135 in web-app/src/containers/DropdownModelProvider.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

132-135 lines are not covered with tests
}, [])

// Clear search and focus input
const onClearSearch = useCallback(() => {
setSearchValue('')
searchInputRef.current?.focus()

Check warning on line 141 in web-app/src/containers/DropdownModelProvider.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

140-141 lines are not covered with tests
}, [])

// Create searchable items from all models
Expand All @@ -152,15 +148,17 @@
providers.forEach((provider) => {
if (!provider.active) return

provider.models.forEach((modelItem) => {

Check warning on line 151 in web-app/src/containers/DropdownModelProvider.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

151 line is not covered with tests
// Skip models that require API key but don't have one (except llamacpp)
if (
provider &&
predefinedProviders.some((e) =>
e.provider.includes(provider.provider)
) && provider.provider !== 'llamacpp' && !provider.api_key?.length
) &&
provider.provider !== 'llamacpp' &&
!provider.api_key?.length
)
return
return

const capabilities = modelItem.capabilities || []
const capabilitiesString = capabilities.join(' ')
Expand Down
Loading