Skip to content

Commit 7eb18c6

Browse files
committed
Custom model for generative features #951
1 parent 6598a0e commit 7eb18c6

34 files changed

+910
-504
lines changed

browser/data-browser/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"clsx": "^2.1.1",
4242
"downshift": "^9.0.9",
4343
"emoji-mart": "^5.6.0",
44-
"ollama-ai-provider": "^1.2.0",
44+
"ollama-ai-provider-v2": "^1.3.1",
4545
"polished": "^4.3.1",
4646
"prismjs": "^1.29.0",
4747
"quick-score": "^0.2.0",

browser/data-browser/src/Providers.tsx

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { AppSettingsContextProvider } from './helpers/AppSettings';
1919
import { NavStateProvider } from './components/NavState';
2020
import { Toaster } from './components/Toaster';
2121
import { McpServersProvider } from './components/AI/MCP/useMcpServers';
22+
import { AISettingsContextProvider } from '@components/AI/AISettingsContext';
2223

2324
// Setup bugsnag for error handling, but only if there's an API key
2425
const ErrBoundary = window.bugsnagApiKey
@@ -45,39 +46,41 @@ export const Providers: React.FC<React.PropsWithChildren> = ({ children }) => {
4546
return (
4647
<NavStateProvider>
4748
<AppSettingsContextProvider>
48-
<McpServersProvider>
49-
<ControlLockProvider>
50-
<HotKeysWrapper>
51-
<StyleSheetManager shouldForwardProp={shouldForwardProp}>
52-
<ThemeWrapper>
53-
<GlobalStyle />
54-
<ErrBoundary FallbackComponent={CrashPage}>
55-
{/* Default form validation provider. Does not do anything on its own but will make sure useValidation works without context*/}
56-
<FormValidationContextProvider
57-
onValidationChange={() => undefined}
58-
>
59-
<Toaster />
60-
<MetaSetter />
61-
<DropdownContainer>
62-
<DialogGlobalContextProvider>
63-
<PopoverContainer>
64-
<DropdownContainer>
65-
<NewResourceUIProvider>
66-
<SkipNav />
67-
<NavWrapper>{children}</NavWrapper>
68-
</NewResourceUIProvider>
69-
</DropdownContainer>
70-
</PopoverContainer>
71-
<NetworkIndicator />
72-
</DialogGlobalContextProvider>
73-
</DropdownContainer>
74-
</FormValidationContextProvider>
75-
</ErrBoundary>
76-
</ThemeWrapper>
77-
</StyleSheetManager>
78-
</HotKeysWrapper>
79-
</ControlLockProvider>
80-
</McpServersProvider>
49+
<AISettingsContextProvider>
50+
<McpServersProvider>
51+
<ControlLockProvider>
52+
<HotKeysWrapper>
53+
<StyleSheetManager shouldForwardProp={shouldForwardProp}>
54+
<ThemeWrapper>
55+
<GlobalStyle />
56+
<ErrBoundary FallbackComponent={CrashPage}>
57+
{/* Default form validation provider. Does not do anything on its own but will make sure useValidation works without context*/}
58+
<FormValidationContextProvider
59+
onValidationChange={() => undefined}
60+
>
61+
<Toaster />
62+
<MetaSetter />
63+
<DropdownContainer>
64+
<DialogGlobalContextProvider>
65+
<PopoverContainer>
66+
<DropdownContainer>
67+
<NewResourceUIProvider>
68+
<SkipNav />
69+
<NavWrapper>{children}</NavWrapper>
70+
</NewResourceUIProvider>
71+
</DropdownContainer>
72+
</PopoverContainer>
73+
<NetworkIndicator />
74+
</DialogGlobalContextProvider>
75+
</DropdownContainer>
76+
</FormValidationContextProvider>
77+
</ErrBoundary>
78+
</ThemeWrapper>
79+
</StyleSheetManager>
80+
</HotKeysWrapper>
81+
</ControlLockProvider>
82+
</McpServersProvider>
83+
</AISettingsContextProvider>
8184
</AppSettingsContextProvider>
8285
</NavStateProvider>
8386
);

browser/data-browser/src/chunks/AI/AIChatPage.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ import {
2121
} from './chatConversionUtils';
2222
import { TagBar } from '@components/Tag/TagBar';
2323
import { RealAIChat } from './RealAIChat';
24+
import { useAISettings } from '@components/AI/AISettingsContext';
2425

2526
const AIChatPage: React.FC<ResourcePageProps<Ai.AiChat>> = ({ resource }) => {
2627
const store = useStore();
28+
const { shouldGenerateTitles } = useAISettings();
2729
const [loading, setLoading] = useState(true);
2830
const [messages, setMessages] = useState<AtomicUIMessage[]>([]);
2931
const [contextItems, setContextItems] = useState<AIMessageContext[]>([]);
@@ -143,7 +145,11 @@ const AIChatPage: React.FC<ResourcePageProps<Ai.AiChat>> = ({ resource }) => {
143145

144146
// When there are only two messages and the title is still the default name, generate a title from the conversation.
145147
useEffect(() => {
146-
if (messages.length === 2 && title === DEFAULT_AICHAT_NAME) {
148+
if (
149+
messages.length === 2 &&
150+
title === DEFAULT_AICHAT_NAME &&
151+
shouldGenerateTitles
152+
) {
147153
generateTitleFromConversation(messages).then(setTitle);
148154
}
149155
}, [messages, title]);

browser/data-browser/src/chunks/AI/AISidebar.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React, { useEffect, useReducer, useRef, useState } from 'react';
33
import { newContextItem, useAISidebar } from '@components/AI/AISidebarContext';
44
import { AIAtomicResourceMessageContext, type AtomicUIMessage } from './types';
55
import { useCurrentSubject } from '@helpers/useCurrentSubject';
6-
import { FaFloppyDisk, FaPlus, FaXmark } from 'react-icons/fa6';
6+
import { FaArrowRotateLeft, FaFloppyDisk, FaXmark } from 'react-icons/fa6';
77
import { IconButton } from '@components/IconButton/IconButton';
88
import { Row } from '@components/Row';
99
import { ParentPickerDialog } from '@components/ParentPicker/ParentPickerDialog';
@@ -13,10 +13,12 @@ import { uiMessageToResource } from './chatConversionUtils';
1313
import { useNavigateWithTransition } from '@hooks/useNavigateWithTransition';
1414
import { constructOpenURL } from '@helpers/navigation';
1515
import { RealAIChat } from './RealAIChat';
16+
import { useAISettings } from '@components/AI/AISettingsContext';
1617

1718
const AISidebar: React.FC = () => {
1819
const store = useStore();
1920
const [rerenderKey, updateRenderKey] = useReducer(prev => prev + 1, 0);
21+
const { shouldGenerateTitles } = useAISettings();
2022
const { isOpen, contextItems, setContextItems, setIsOpen } = useAISidebar();
2123
const [messages, setMessages] = useState<AtomicUIMessage[]>([]);
2224
const [currentSubject] = useCurrentSubject();
@@ -106,6 +108,13 @@ const AISidebar: React.FC = () => {
106108

107109
useEffect(() => {
108110
if (messages.length > 2 && !titlePromiseRef.current) {
111+
if (!shouldGenerateTitles) {
112+
// Don't generate a title, just resolve the promise.
113+
titlePromiseRef.current = Promise.resolve(undefined);
114+
115+
return;
116+
}
117+
109118
titlePromiseRef.current = generateTitleFromConversation(messages);
110119
}
111120
}, [messages]);
@@ -129,7 +138,7 @@ const AISidebar: React.FC = () => {
129138
color='textLight'
130139
style={{ alignSelf: 'flex-end' }}
131140
>
132-
<FaPlus />
141+
<FaArrowRotateLeft />
133142
</IconButton>
134143
<Heading>Atomic Assistant</Heading>
135144
</Row>

0 commit comments

Comments
 (0)