fixsta
This commit is contained in:
parent
086e311aa4
commit
1cebb80b08
1
.gitignore
vendored
1
.gitignore
vendored
@ -39,3 +39,4 @@ yarn-error.log*
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
/electron-file-search/datahound-win32-x64
|
||||
|
9
Modelfile
Normal file
9
Modelfile
Normal file
@ -0,0 +1,9 @@
|
||||
FROM deepseek-r1:1.5b
|
||||
# Disable GPU usage
|
||||
PARAMETER num_gpu 0
|
||||
|
||||
# Increase context length
|
||||
PARAMETER max_tokens 16384
|
||||
|
||||
# Set temperature to 0.6
|
||||
PARAMETER temperature 0.6
|
@ -148,7 +148,7 @@ export class LLMService {
|
||||
|
||||
case 'ollama':
|
||||
const ollamaResponse = await ollamaService.chat({
|
||||
model: this.#config.model || 'phi4:latest',
|
||||
model: this.#config.model || 'llama2:7b',
|
||||
messages: [{ role: 'user', content: question }],
|
||||
temperature: this.#config.temperature,
|
||||
onChunk,
|
||||
@ -195,7 +195,7 @@ export class LLMService {
|
||||
const cleanConfig = {
|
||||
provider: newConfig.provider,
|
||||
apiKey: newConfig.apiKey ?? null,
|
||||
model: newConfig.model ?? (newConfig.provider === 'ollama' ? 'phi4' : null),
|
||||
model: newConfig.model ?? (newConfig.provider === 'ollama' ? 'llama2:7b' : null),
|
||||
baseUrl: newConfig.provider === 'ollama' ? (newConfig.baseUrl ?? 'http://localhost:11434') : (newConfig.baseUrl ?? null),
|
||||
temperature: typeof newConfig.temperature === 'number' ? newConfig.temperature : 0.7
|
||||
};
|
||||
|
@ -58,7 +58,7 @@ const schema: Store.Schema<Schema> = {
|
||||
additionalProperties: false,
|
||||
default: {
|
||||
provider: 'ollama',
|
||||
model: 'phi4',
|
||||
model: 'llama2:7b',
|
||||
baseUrl: 'http://localhost:11434',
|
||||
temperature: 0.7
|
||||
}
|
||||
|
10
electron-file-search/package-lock.json
generated
10
electron-file-search/package-lock.json
generated
@ -17,6 +17,7 @@
|
||||
"chokidar": "^3.5.3",
|
||||
"electron-store": "^8.1.0",
|
||||
"highlight.js": "^11.11.1",
|
||||
"lucide-react": "^0.474.0",
|
||||
"ollama": "^0.5.12",
|
||||
"openai": "^4.82.0",
|
||||
"openrouter-client": "^1.2.0",
|
||||
@ -6546,6 +6547,15 @@
|
||||
"yallist": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/lucide-react": {
|
||||
"version": "0.474.0",
|
||||
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.474.0.tgz",
|
||||
"integrity": "sha512-CmghgHkh0OJNmxGKWc0qfPJCYHASPMVSyGY8fj3xgk4v84ItqDg64JNKFZn5hC6E0vHi6gxnbCgwhyVB09wQtA==",
|
||||
"license": "ISC",
|
||||
"peerDependencies": {
|
||||
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/matcher": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
|
||||
|
@ -20,6 +20,7 @@
|
||||
"chokidar": "^3.5.3",
|
||||
"electron-store": "^8.1.0",
|
||||
"highlight.js": "^11.11.1",
|
||||
"lucide-react": "^0.474.0",
|
||||
"ollama": "^0.5.12",
|
||||
"openai": "^4.82.0",
|
||||
"openrouter-client": "^1.2.0",
|
||||
|
@ -149,6 +149,18 @@ function AppContent() {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flex: 1,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
Data Hound V2
|
||||
</Box>
|
||||
<div className="window-controls">
|
||||
<button
|
||||
className="control-button"
|
||||
@ -247,15 +259,48 @@ function AppContent() {
|
||||
boxSizing: 'border-box'
|
||||
}}
|
||||
>
|
||||
<TextField
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
placeholder="Ask a question..."
|
||||
value={input}
|
||||
onChange={(e) => setInput(e.target.value)}
|
||||
disabled={isLoading}
|
||||
size="small"
|
||||
/>
|
||||
<TextField
|
||||
fullWidth
|
||||
multiline
|
||||
variant="outlined"
|
||||
placeholder="Ask a question..."
|
||||
value={input}
|
||||
onChange={(e) => setInput(e.target.value)}
|
||||
disabled={isLoading}
|
||||
size="small"
|
||||
minRows={1}
|
||||
maxRows={4}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === 'Enter') {
|
||||
if (event.shiftKey) {
|
||||
return; // Allow new line with Shift+Enter
|
||||
}
|
||||
event.preventDefault();
|
||||
handleSubmit(event);
|
||||
}
|
||||
}}
|
||||
InputProps={{
|
||||
style: {
|
||||
resize: 'vertical'
|
||||
},
|
||||
sx: {
|
||||
'&::-webkit-scrollbar': {
|
||||
width: '8px',
|
||||
background: 'transparent',
|
||||
},
|
||||
'&::-webkit-scrollbar-thumb': {
|
||||
background: (theme) => theme.palette.primary.main, // Using your theme's primary blue
|
||||
borderRadius: '2px', // Made more square
|
||||
'&:hover': {
|
||||
background: (theme) => theme.palette.primary.light, // Lighter blue on hover
|
||||
},
|
||||
},
|
||||
'&::-webkit-scrollbar-track': {
|
||||
background: 'transparent',
|
||||
},
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<IconButton
|
||||
type="submit"
|
||||
disabled={isLoading || !input.trim()}
|
||||
|
@ -1,9 +1,10 @@
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { Box, Typography, Paper, Avatar } from '@mui/material';
|
||||
import type { DocumentMetadata } from '../../../electron/types';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { Box, Typography, Paper, Avatar, Collapse, IconButton } from '@mui/material';
|
||||
import { Loader2, ChevronDown, ChevronUp } from 'lucide-react';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import rehypeHighlight from 'rehype-highlight';
|
||||
import 'highlight.js/styles/github.css';
|
||||
import type { DocumentMetadata } from '../../../electron/types';
|
||||
|
||||
interface ChatMessage {
|
||||
id: string;
|
||||
@ -18,8 +19,220 @@ interface MessageListProps {
|
||||
messages: ChatMessage[];
|
||||
}
|
||||
|
||||
export default function MessageList({ messages }: MessageListProps) {
|
||||
const messageListRef = useRef<HTMLDivElement>(null);
|
||||
interface ThinkingContentProps {
|
||||
content: string;
|
||||
isThinking: boolean;
|
||||
}
|
||||
|
||||
interface MessageSegment {
|
||||
type: 'text' | 'thinking';
|
||||
content: string;
|
||||
inProgress?: boolean;
|
||||
}
|
||||
|
||||
interface MessageContentProps {
|
||||
text: string;
|
||||
}
|
||||
|
||||
const ThinkingContent: React.FC<ThinkingContentProps> = ({ content, isThinking }) => {
|
||||
const [isExpanded, setIsExpanded] = useState<boolean>(false);
|
||||
|
||||
return (
|
||||
<Box sx={{ mt: 1 }}>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 1,
|
||||
cursor: 'pointer',
|
||||
color: 'text.secondary'
|
||||
}}
|
||||
onClick={() => setIsExpanded(!isExpanded)}
|
||||
>
|
||||
<IconButton size="small">
|
||||
{isExpanded ? <ChevronUp size={16} /> : <ChevronDown size={16} />}
|
||||
</IconButton>
|
||||
<Typography variant="caption" sx={{ fontWeight: 500 }}>
|
||||
Thinking Process
|
||||
</Typography>
|
||||
{isThinking && (
|
||||
<Box
|
||||
component={Loader2}
|
||||
size={16}
|
||||
className="animate-spin"
|
||||
sx={{
|
||||
animation: 'spin 1s linear infinite',
|
||||
'@keyframes spin': {
|
||||
'0%': {
|
||||
transform: 'rotate(0deg)',
|
||||
},
|
||||
'100%': {
|
||||
transform: 'rotate(360deg)',
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
<Collapse in={isExpanded}>
|
||||
<Box sx={{
|
||||
pl: 4,
|
||||
pr: 2,
|
||||
py: 1,
|
||||
mt: 1,
|
||||
borderLeft: '2px solid',
|
||||
borderColor: 'divider',
|
||||
color: 'text.secondary'
|
||||
}}>
|
||||
<ReactMarkdown
|
||||
className="markdown-body"
|
||||
rehypePlugins={[rehypeHighlight]}
|
||||
>
|
||||
{content}
|
||||
</ReactMarkdown>
|
||||
</Box>
|
||||
</Collapse>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const MessageContent: React.FC<MessageContentProps> = ({ text }) => {
|
||||
const [segments, setSegments] = useState<MessageSegment[]>([]);
|
||||
const [isThinking, setIsThinking] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
const parseContent = (): void => {
|
||||
const parts: MessageSegment[] = [];
|
||||
let remainingText = text;
|
||||
|
||||
// Handle <think> tags
|
||||
const thinkRegex = /<think>([\s\S]*?)(?:<\/think>|$)/g;
|
||||
let lastIndex = 0;
|
||||
let match;
|
||||
|
||||
while ((match = thinkRegex.exec(text)) !== null) {
|
||||
// Add text before the think tag if there is any
|
||||
const beforeText = text.slice(lastIndex, match.index).trim();
|
||||
if (beforeText) {
|
||||
parts.push({
|
||||
type: 'text',
|
||||
content: beforeText
|
||||
});
|
||||
}
|
||||
|
||||
// Add the thinking content
|
||||
parts.push({
|
||||
type: 'thinking',
|
||||
content: match[1],
|
||||
inProgress: !match[0].endsWith('</think>')
|
||||
});
|
||||
|
||||
lastIndex = match.index + match[0].length;
|
||||
}
|
||||
|
||||
// Add any remaining text after the last think tag
|
||||
const afterText = text.slice(lastIndex).trim();
|
||||
if (afterText) {
|
||||
parts.push({
|
||||
type: 'text',
|
||||
content: afterText
|
||||
});
|
||||
}
|
||||
|
||||
setSegments(parts);
|
||||
setIsThinking(parts.some(part => part.type === 'thinking' && part.inProgress));
|
||||
};
|
||||
|
||||
parseContent();
|
||||
}, [text]);
|
||||
|
||||
return (
|
||||
<Box>
|
||||
{segments.map((segment, index) => {
|
||||
if (segment.type === 'text' && segment.content.trim()) {
|
||||
return (
|
||||
<Box key={index}>
|
||||
<Box sx={{
|
||||
'& .markdown-body': {
|
||||
whiteSpace: 'pre-wrap',
|
||||
wordBreak: 'break-word',
|
||||
minHeight: '1.5em',
|
||||
lineHeight: 1.6,
|
||||
'& pre': {
|
||||
backgroundColor: (theme) => theme.palette.mode === 'dark' ? '#1e1e1e' : '#f6f8fa',
|
||||
padding: 2,
|
||||
borderRadius: 1,
|
||||
overflow: 'auto'
|
||||
},
|
||||
'& code': {
|
||||
backgroundColor: (theme) => theme.palette.mode === 'dark' ? '#1e1e1e' : '#f6f8fa',
|
||||
padding: '0.2em 0.4em',
|
||||
borderRadius: 1,
|
||||
fontSize: '85%'
|
||||
},
|
||||
'& h1, & h2, & h3, & h4, & h5, & h6': {
|
||||
marginTop: '24px',
|
||||
marginBottom: '16px',
|
||||
fontWeight: 600,
|
||||
lineHeight: 1.25
|
||||
},
|
||||
'& p': {
|
||||
marginTop: '0',
|
||||
marginBottom: '16px'
|
||||
},
|
||||
'& a': {
|
||||
color: (theme) => theme.palette.primary.main,
|
||||
textDecoration: 'none',
|
||||
'&:hover': {
|
||||
textDecoration: 'underline'
|
||||
}
|
||||
},
|
||||
'& img': {
|
||||
maxWidth: '100%',
|
||||
height: 'auto'
|
||||
},
|
||||
'& blockquote': {
|
||||
padding: '0 1em',
|
||||
color: (theme) => theme.palette.text.secondary,
|
||||
borderLeft: (theme) => `0.25em solid ${theme.palette.divider}`,
|
||||
margin: '0 0 16px 0'
|
||||
},
|
||||
'& ul, & ol': {
|
||||
paddingLeft: '2em',
|
||||
marginBottom: '16px'
|
||||
}
|
||||
}
|
||||
}}>
|
||||
<ReactMarkdown
|
||||
className="markdown-body"
|
||||
rehypePlugins={[rehypeHighlight]}
|
||||
>
|
||||
{segment.content}
|
||||
</ReactMarkdown>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
if (segment.type === 'thinking') {
|
||||
return (
|
||||
<Box key={index}>
|
||||
<ThinkingContent
|
||||
content={segment.content}
|
||||
isThinking={segment.inProgress || false}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
})}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const MessageList: React.FC<MessageListProps> = ({ messages }) => {
|
||||
// Memoize messages to preserve their original timestamps
|
||||
const memoizedMessages = React.useMemo(() => messages, [messages]);
|
||||
const messageListRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (messageListRef.current) {
|
||||
@ -49,11 +262,9 @@ export default function MessageList({ messages }: MessageListProps) {
|
||||
background: (theme) => theme.palette.action.hover,
|
||||
},
|
||||
},
|
||||
'&::-webkit-scrollbar-track': {
|
||||
background: 'transparent',
|
||||
},
|
||||
}}>
|
||||
{messages.map((message) => (
|
||||
}}
|
||||
>
|
||||
{memoizedMessages.map((message) => (
|
||||
<Box
|
||||
key={message.id}
|
||||
sx={{
|
||||
@ -65,142 +276,45 @@ export default function MessageList({ messages }: MessageListProps) {
|
||||
alignSelf: message.isUser ? 'flex-end' : 'flex-start',
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 0.5 }}>
|
||||
<Avatar
|
||||
src={message.isUser ? '/profiles/user-profile.webp' : '/profiles/ai-profile.webp'}
|
||||
alt={message.isUser ? 'User' : 'AI'}
|
||||
variant="square"
|
||||
sx={{
|
||||
width: 40,
|
||||
height: 40,
|
||||
boxShadow: 1
|
||||
}}
|
||||
/>
|
||||
<Typography
|
||||
variant="caption"
|
||||
sx={{
|
||||
fontSize: '0.75rem',
|
||||
color: 'text.secondary',
|
||||
fontWeight: 500
|
||||
}}
|
||||
>
|
||||
{message.isUser ? 'User' : 'Data Hound'}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
component={Paper}
|
||||
<Avatar
|
||||
src={message.isUser ? '/profiles/user-profile.webp' : '/profiles/ai-profile.webp'}
|
||||
alt={message.isUser ? 'User' : 'AI'}
|
||||
sx={{ width: 40, height: 40 }}
|
||||
/>
|
||||
<Paper
|
||||
elevation={1}
|
||||
sx={{
|
||||
p: 2,
|
||||
flex: 1,
|
||||
bgcolor: message.isUser ? 'primary.main' : 'background.paper',
|
||||
color: message.isUser ? 'primary.contrastText' : 'text.primary',
|
||||
transition: 'all 0.2s ease-in-out',
|
||||
boxShadow: 1,
|
||||
borderRadius: 2,
|
||||
'&:hover': {
|
||||
boxShadow: 2,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Box sx={{
|
||||
'& .markdown-body': {
|
||||
whiteSpace: 'pre-wrap',
|
||||
wordBreak: 'break-word',
|
||||
minHeight: '1.5em',
|
||||
lineHeight: 1.6,
|
||||
'& pre': {
|
||||
backgroundColor: (theme) => theme.palette.mode === 'dark' ? '#1e1e1e' : '#f6f8fa',
|
||||
padding: 2,
|
||||
borderRadius: 1,
|
||||
overflow: 'auto'
|
||||
},
|
||||
'& code': {
|
||||
backgroundColor: (theme) => theme.palette.mode === 'dark' ? '#1e1e1e' : '#f6f8fa',
|
||||
padding: '0.2em 0.4em',
|
||||
borderRadius: 1,
|
||||
fontSize: '85%'
|
||||
},
|
||||
'& h1, & h2, & h3, & h4, & h5, & h6': {
|
||||
marginTop: '24px',
|
||||
marginBottom: '16px',
|
||||
fontWeight: 600,
|
||||
lineHeight: 1.25
|
||||
},
|
||||
'& p': {
|
||||
marginTop: '0',
|
||||
marginBottom: '16px'
|
||||
},
|
||||
'& a': {
|
||||
color: (theme) => theme.palette.primary.main,
|
||||
textDecoration: 'none',
|
||||
'&:hover': {
|
||||
textDecoration: 'underline'
|
||||
}
|
||||
},
|
||||
'& img': {
|
||||
maxWidth: '100%',
|
||||
height: 'auto'
|
||||
},
|
||||
'& blockquote': {
|
||||
padding: '0 1em',
|
||||
color: (theme) => theme.palette.text.secondary,
|
||||
borderLeft: (theme) => `0.25em solid ${theme.palette.divider}`,
|
||||
margin: '0 0 16px 0'
|
||||
},
|
||||
'& ul, & ol': {
|
||||
paddingLeft: '2em',
|
||||
marginBottom: '16px'
|
||||
}
|
||||
}
|
||||
}}>
|
||||
<ReactMarkdown
|
||||
className="markdown-body"
|
||||
rehypePlugins={[rehypeHighlight]}
|
||||
>
|
||||
{message.text}
|
||||
</ReactMarkdown>
|
||||
</Box>
|
||||
{message.sources && message.sources.length > 0 && (
|
||||
<Box sx={{ mt: 2, pt: 1, borderTop: '1px solid', borderColor: 'divider' }}>
|
||||
<Typography
|
||||
variant="caption"
|
||||
color="text.secondary"
|
||||
sx={{
|
||||
display: 'block',
|
||||
mb: 0.5,
|
||||
fontWeight: 'medium'
|
||||
}}
|
||||
>
|
||||
Sources:
|
||||
</Typography>
|
||||
{message.sources.map((source, index) => (
|
||||
<Typography
|
||||
key={index}
|
||||
variant="caption"
|
||||
component="div"
|
||||
color="text.secondary"
|
||||
sx={{
|
||||
pl: 1,
|
||||
borderLeft: '2px solid',
|
||||
borderColor: 'divider'
|
||||
}}
|
||||
>
|
||||
{source.path}
|
||||
</Typography>
|
||||
))}
|
||||
</Box>
|
||||
)}
|
||||
<Typography
|
||||
variant="caption"
|
||||
color={message.isUser ? '#ffffff' : 'text.secondary'}
|
||||
sx={{ display: 'block', mt: 0.5 }}
|
||||
px: 2,
|
||||
py: 1.5,
|
||||
flex: 1,
|
||||
bgcolor: message.isUser ? 'primary.main' : 'background.paper',
|
||||
color: message.isUser ? 'primary.contrastText' : 'text.primary',
|
||||
borderRadius: 2,
|
||||
}}
|
||||
>
|
||||
{new Date(message.timestamp).toLocaleTimeString()}
|
||||
</Typography>
|
||||
</Box>
|
||||
<MessageContent text={message.text} />
|
||||
{message.sources && message.sources.length > 0 && (
|
||||
<Box sx={{ mt: 2, pt: 1, borderTop: '1px solid', borderColor: 'divider' }}>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
Sources:
|
||||
</Typography>
|
||||
{message.sources.map((source, index) => (
|
||||
<Typography
|
||||
key={index}
|
||||
variant="caption"
|
||||
component="div"
|
||||
color="text.secondary"
|
||||
>
|
||||
{source.path}
|
||||
</Typography>
|
||||
))}
|
||||
</Box>
|
||||
)}
|
||||
</Paper>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default MessageList;
|
@ -13,6 +13,8 @@ import {
|
||||
Alert,
|
||||
Box,
|
||||
Typography,
|
||||
TextField,
|
||||
InputAdornment,
|
||||
} from '@mui/material';
|
||||
import {
|
||||
Folder as FolderIcon,
|
||||
@ -21,7 +23,10 @@ import {
|
||||
Cloud as DropboxIcon,
|
||||
Chat as DiscordIcon,
|
||||
Computer as LocalIcon,
|
||||
Search,
|
||||
Padding
|
||||
} from '@mui/icons-material';
|
||||
|
||||
import { useElectron } from '../../hooks/useElectron';
|
||||
|
||||
interface Directory {
|
||||
@ -105,16 +110,46 @@ export default function DirectoryPicker({ onSelect }: DirectoryPickerProps) {
|
||||
mr: 2,
|
||||
mb: 2,
|
||||
}}>
|
||||
<Typography sx={{ pl:2 ,flexGrow: 1 }} variant="h6">Folders</Typography>
|
||||
<Button
|
||||
|
||||
<TextField
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
size="small"
|
||||
placeholder="Search..."
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<Search className="text-gray-400"/>
|
||||
|
||||
</InputAdornment>
|
||||
),
|
||||
sx: {ml:2,
|
||||
'&::-webkit-scrollbar': {
|
||||
width: '8px',
|
||||
background: 'transparent',
|
||||
},
|
||||
'&::-webkit-scrollbar-thumb': {
|
||||
background: '#2196f3',
|
||||
borderRadius: '2px',
|
||||
'&:hover': {
|
||||
background: '#64b5f6',
|
||||
},
|
||||
},
|
||||
'&::-webkit-scrollbar-track': {
|
||||
background: 'transparent',
|
||||
}
|
||||
}
|
||||
}}
|
||||
/> <Button
|
||||
variant="contained"
|
||||
onClick={handleOpen}
|
||||
size="small"
|
||||
sx={{
|
||||
ml:3,
|
||||
minWidth: 0,
|
||||
width: '32px',
|
||||
height: '32px',
|
||||
borderRadius: '50%',
|
||||
width: '64px',
|
||||
height: '38px',
|
||||
borderRadius: '5%',
|
||||
padding: 0,
|
||||
overflow: 'hidden',
|
||||
backgroundColor: 'primary.main',
|
||||
@ -130,10 +165,10 @@ export default function DirectoryPicker({ onSelect }: DirectoryPickerProps) {
|
||||
},
|
||||
'&:hover': {
|
||||
backgroundColor: 'primary.dark',
|
||||
width: '180px',
|
||||
borderRadius: '16px',
|
||||
width: '400%',
|
||||
borderRadius: '5%',
|
||||
'& .buttonText': {
|
||||
width: '110px',
|
||||
width: '150px',
|
||||
marginLeft: '8px',
|
||||
},
|
||||
},
|
||||
|
@ -22,7 +22,7 @@ export function useLLMConfig() {
|
||||
});
|
||||
setConfig(config || {
|
||||
provider: 'ollama',
|
||||
model: 'phi4',
|
||||
model: 'llama2:7b',
|
||||
baseUrl: 'http://localhost:11434',
|
||||
temperature: 0.7,
|
||||
apiKey: undefined
|
||||
|
Loading…
x
Reference in New Issue
Block a user