-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0175511
commit 261cb5b
Showing
14 changed files
with
323 additions
and
123 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
152 changes: 86 additions & 66 deletions
152
packages/keepkey-desktop-app/src/components/Modals/Settings/OllamaSettings.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,89 +1,109 @@ | ||
import { Divider, HStack, Stack } from '@chakra-ui/layout'; | ||
import React, { FC, useEffect, useState } from 'react'; | ||
import { Stack, Divider, Box, Avatar, Link, Text } from '@chakra-ui/react'; | ||
import { ExternalLinkIcon } from '@chakra-ui/icons'; | ||
import { Avatar, Link, Button, Icon, Text } from '@chakra-ui/react'; | ||
import { useModal } from 'hooks/useModal/useModal'; | ||
import { useEffect, useState } from 'react'; | ||
import { FaTrash } from 'react-icons/fa'; | ||
import { HiRefresh } from 'react-icons/hi'; | ||
import { IoFileTray } from 'react-icons/io5'; | ||
import { TbRefreshAlert } from 'react-icons/tb'; | ||
import { MdPlayArrow, MdStop, MdViewList } from 'react-icons/md'; | ||
import { FC } from 'react'; | ||
import axios from 'axios'; | ||
|
||
import bex from 'assets/ollama.png'; | ||
import { SettingsListItem } from './SettingsListItem'; | ||
import OllamaStatus from './ollama/OllamaStatus'; | ||
import ModelSelector from './ollama/ModelSelector'; | ||
import ModelInstaller from './ollama/ModelInstaller'; | ||
import Logs from './ollama/Logs'; | ||
// @ts-ignore | ||
import { Ollama } from 'keepkey-ollama/browser'; | ||
|
||
interface OllamaSettingsProps { | ||
shouldAutoUpdate: boolean; | ||
shouldMinimizeToTray: boolean; | ||
allowPreRelease: boolean; | ||
autoScanQr: boolean; | ||
interface KnownModel { | ||
name: string; | ||
sizes: string[]; | ||
} | ||
|
||
export const OllamaSettings: FC = () => { | ||
const { settings, onboardingSteps } = useModal(); | ||
const [appSettings, setAppSettings] = useState<OllamaSettingsProps>({ | ||
shouldAutoUpdate: true, | ||
shouldMinimizeToTray: true, | ||
allowPreRelease: false, | ||
autoScanQr: false, | ||
}); | ||
|
||
const [prevAppSettings, setPrevAppSettings] = useState<OllamaSettingsProps>(appSettings); | ||
const [isOllamaRunning, setIsOllamaRunning] = useState(false); | ||
|
||
const handleTestConnection = async () => { | ||
const [installedModels, setInstalledModels] = useState<string[]>([]); | ||
const [selectedModel, setSelectedModel] = useState(''); | ||
const [needToInstall, setNeedToInstall] = useState(false); | ||
const [logs, setLogs] = useState<string[]>([]); | ||
const [showLogs, setShowLogs] = useState(false); | ||
|
||
const knownModels: KnownModel[] = [ | ||
{ name: 'llama-3.2', sizes: ['small', 'medium', 'large'] }, | ||
{ name: 'gemma-2', sizes: ['small', 'medium'] }, | ||
{ name: 'dolphin-mixtral', sizes: ['medium', 'large'] }, | ||
]; | ||
|
||
const listInstalledModels = async () => { | ||
try { | ||
const response = await axios.get('http://127.0.0.1:11434/'); | ||
console.log('Ollama is healthy:', response.data); | ||
setIsOllamaRunning(true); | ||
const response = await Ollama.list(); | ||
setInstalledModels(response.models); | ||
} catch (error) { | ||
console.error('Ollama is not responding:', error); | ||
setIsOllamaRunning(false); | ||
console.error('Error listing models:', error); | ||
setLogs((prevLogs) => [...prevLogs, `Error listing models: ${error}`]); | ||
} | ||
}; | ||
|
||
useEffect(() => { | ||
handleTestConnection(); | ||
}, []); | ||
const handleModelSelect = (modelName: string) => { | ||
setSelectedModel(modelName); | ||
setNeedToInstall(!installedModels.includes(modelName)); | ||
}; | ||
|
||
const handleInstallComplete = () => { | ||
// After installation, refresh the installed models list | ||
listInstalledModels(); | ||
setNeedToInstall(false); | ||
}; | ||
|
||
useEffect(() => { | ||
if ( | ||
prevAppSettings && | ||
appSettings.shouldAutoUpdate === prevAppSettings.shouldAutoUpdate && | ||
appSettings.shouldMinimizeToTray === prevAppSettings.shouldMinimizeToTray && | ||
appSettings.allowPreRelease === prevAppSettings.allowPreRelease && | ||
appSettings.autoScanQr === prevAppSettings.autoScanQr | ||
) return; | ||
|
||
setPrevAppSettings(appSettings); | ||
console.log('APP SETTINGS SAVED', appSettings); | ||
}, [appSettings, prevAppSettings]); | ||
listInstalledModels(); | ||
}, []); | ||
|
||
return ( | ||
<Stack width='full' p={0}> | ||
<Stack width="full" p={0}> | ||
<Divider my={1} /> | ||
<Link href='http://127.0.0.1:11434/' isExternal> | ||
<Box maxW={{ base: '100%', md: '45%' }} mb={{ base: 4, md: 0 }} mx="auto"> | ||
<Avatar src={bex} size="lg" /> | ||
</Box> | ||
|
||
<Link href="http://127.0.0.1:11434/" isExternal> | ||
<SettingsListItem | ||
icon={<Icon as={ExternalLinkIcon} color='gray.500' />} | ||
label='connectWallet.menu.openDev' | ||
icon={<ExternalLinkIcon color="gray.500" />} | ||
label="Open Ollama" | ||
/> | ||
</Link> | ||
|
||
<Divider my={1} /> | ||
<HStack> | ||
<SettingsListItem | ||
label={'Test Connection'} | ||
onClick={handleTestConnection} | ||
icon={<Icon as={HiRefresh} color='gray.500' />} | ||
> | ||
<Button variant={'ghost'} onClick={handleTestConnection}> | ||
Test | ||
</Button> | ||
</SettingsListItem> | ||
<Text color={isOllamaRunning ? 'green.500' : 'red.500'}> | ||
{isOllamaRunning ? 'Online' : 'Offline'} | ||
</Text> | ||
</HStack> | ||
|
||
{/* Model Selector */} | ||
<ModelSelector | ||
installedModels={installedModels} | ||
knownModels={knownModels} | ||
onModelSelect={handleModelSelect} | ||
/> | ||
|
||
<Divider my={1} /> | ||
|
||
{/* Install Model if needed */} | ||
{needToInstall && selectedModel && ( | ||
<> | ||
<ModelInstaller | ||
modelName={selectedModel} | ||
onInstallComplete={handleInstallComplete} | ||
setLogs={setLogs} | ||
/> | ||
<Divider my={1} /> | ||
</> | ||
)} | ||
|
||
{/* Link to find more models */} | ||
<Link href="https://ollama.com/library" isExternal> | ||
Find more models | ||
</Link> | ||
|
||
<Divider my={1} /> | ||
|
||
{/* Ollama Status */} | ||
<OllamaStatus /> | ||
|
||
<Divider my={1} /> | ||
|
||
{/* Logs Section */} | ||
<Logs logs={logs} showLogs={showLogs} setShowLogs={setShowLogs} /> | ||
</Stack> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
packages/keepkey-desktop-app/src/components/Modals/Settings/ollama/Logs.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import React, { FC } from 'react'; | ||
import { Box, Button, Text, Icon } from '@chakra-ui/react'; | ||
import { MdViewList } from 'react-icons/md'; | ||
|
||
interface LogsProps { | ||
logs: string[]; | ||
showLogs: boolean; | ||
setShowLogs: React.Dispatch<React.SetStateAction<boolean>>; | ||
} | ||
|
||
const Logs: FC<LogsProps> = ({ logs, showLogs, setShowLogs }) => { | ||
return ( | ||
<Box> | ||
<Button variant="ghost" onClick={() => setShowLogs((prev) => !prev)}> | ||
{showLogs ? 'Hide Logs' : 'Show Logs'} | ||
<Icon as={MdViewList} ml={2} /> | ||
</Button> | ||
{showLogs && ( | ||
<Box p={2} maxH="200px" overflowY="auto" border="1px solid gray"> | ||
{logs.map((log, index) => ( | ||
<Text key={index} fontSize="sm"> | ||
{log} | ||
</Text> | ||
))} | ||
</Box> | ||
)} | ||
</Box> | ||
); | ||
}; | ||
|
||
export default Logs; |
Oops, something went wrong.