-
Notifications
You must be signed in to change notification settings - Fork 2.6k
ui: new configure provider flow #1736
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,7 +11,7 @@ | |
| import { ToastContainer } from 'react-toastify'; | ||
| import { extractExtensionName } from './components/settings/extensions/utils'; | ||
| import { GoosehintsModal } from './components/GoosehintsModal'; | ||
| import { SessionDetails, fetchSessionDetails } from './sessions'; | ||
|
|
||
| import WelcomeView from './components/WelcomeView'; | ||
| import ChatView from './components/ChatView'; | ||
|
|
@@ -49,7 +49,7 @@ | |
| | { | ||
| resumedSession?: SessionDetails; | ||
| } | ||
| | Record<string, any>; | ||
| }; | ||
|
|
||
| export default function App() { | ||
|
|
@@ -62,9 +62,17 @@ | |
| view: 'welcome', | ||
| viewOptions: {}, | ||
| }); | ||
| const { getExtensions, addExtension } = useConfig(); | ||
| const { getExtensions, addExtension, read } = useConfig(); | ||
| const initAttemptedRef = useRef(false); | ||
|
|
||
| // Utility function to extract the command from the link | ||
| function extractCommand(link: string): string { | ||
| const url = new URL(link); | ||
| const cmd = url.searchParams.get('cmd') || 'Unknown Command'; | ||
| const args = url.searchParams.getAll('arg').map(decodeURIComponent); | ||
| return `${cmd} ${args.join(' ')}`.trim(); | ||
| } | ||
|
|
||
| useEffect(() => { | ||
| // Skip if feature flag is not enabled | ||
| if (!process.env.ALPHA) { | ||
|
|
@@ -94,46 +102,42 @@ | |
| } | ||
| }; | ||
|
|
||
| setupExtensions(); | ||
| }, []); // Empty dependency array since we're using initAttemptedRef | ||
| const initializeApp = async () => { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. new way to initialize app -- can break into separate useEffect's when we're ready |
||
| try { | ||
| // Check if we have the required configuration | ||
| const provider = (await read('GOOSE_PROVIDER', false)) as string; | ||
| const model = (await read('GOOSE_MODEL', false)) as string; | ||
|
|
||
| if (provider && model) { | ||
| // We have all needed configuration, initialize the system | ||
| console.log('Initializing system with stored GOOSE_MODEL and GOOSE_PROVIDER'); | ||
| await initializeSystem(provider, model); | ||
| setView('chat'); | ||
| } else { | ||
| // Missing configuration, show onboarding | ||
| console.log('Missing configuration, showing onboarding'); | ||
| setView('welcome'); | ||
| } | ||
| } catch (error) { | ||
| console.error('Error initializing app:', error); | ||
| setView('welcome'); | ||
| } | ||
| }; | ||
|
|
||
| const [isGoosehintsModalOpen, setIsGoosehintsModalOpen] = useState(false); | ||
| const [isLoadingSession, setIsLoadingSession] = useState(false); | ||
| initializeApp().then(); | ||
| setupExtensions().then(); | ||
| }, []); // Empty dependency array since we're using initAttemptedRef | ||
|
|
||
| const { switchModel } = useModel(); | ||
| const { addRecentModel } = useRecentModels(); | ||
| const setView = (view: View, viewOptions: Record<any, any> = {}) => { | ||
|
Check warning on line 131 in ui/desktop/src/App.tsx
|
||
| setInternalView({ view, viewOptions }); | ||
| }; | ||
|
|
||
| // Utility function to extract the command from the link | ||
| function extractCommand(link: string): string { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not gone just moved -- always available |
||
| const url = new URL(link); | ||
| const cmd = url.searchParams.get('cmd') || 'Unknown Command'; | ||
| const args = url.searchParams.getAll('arg').map(decodeURIComponent); | ||
| return `${cmd} ${args.join(' ')}`.trim(); | ||
| } | ||
| const [isGoosehintsModalOpen, setIsGoosehintsModalOpen] = useState(false); | ||
| const [isLoadingSession, setIsLoadingSession] = useState(false); | ||
| const { chat, setChat } = useChat({ setView, setIsLoadingSession }); | ||
|
|
||
| useEffect(() => window.electron.reactReady(), []); | ||
|
|
||
| useEffect(() => { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not gone just moved -- this always runs |
||
| const handleAddExtension = (_: any, link: string) => { | ||
| const command = extractCommand(link); | ||
| const extName = extractExtensionName(link); | ||
| window.electron.logInfo(`Adding extension from deep link ${link}`); | ||
| setPendingLink(link); | ||
| setModalMessage( | ||
| `Are you sure you want to install the ${extName} extension?\n\nCommand: ${command}` | ||
| ); | ||
| setModalVisible(true); | ||
| }; | ||
|
|
||
| window.electron.on('add-extension', handleAddExtension); | ||
| return () => { | ||
| window.electron.off('add-extension', handleAddExtension); | ||
| }; | ||
| }, []); | ||
|
|
||
| // Keyboard shortcut handler | ||
| useEffect(() => { | ||
| const handleKeyDown = (event: KeyboardEvent) => { | ||
|
|
@@ -149,55 +153,8 @@ | |
| }; | ||
| }, []); | ||
|
|
||
| // Attempt to detect config for a stored provider | ||
| useEffect(() => { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. moved into separate hook below (ctrl+f for |
||
| const config = window.electron.getConfig(); | ||
| const storedProvider = getStoredProvider(config); | ||
| if (storedProvider) { | ||
| setView('chat'); | ||
| } else { | ||
| setView('welcome'); | ||
| } | ||
| }, []); | ||
|
|
||
| // Initialize system if we have a stored provider | ||
| useEffect(() => { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. moved into conditional hook -- look for |
||
| const setupStoredProvider = async () => { | ||
| const config = window.electron.getConfig(); | ||
|
|
||
| if (config.GOOSE_PROVIDER && config.GOOSE_MODEL) { | ||
| window.electron.logInfo( | ||
| 'Initializing system with environment: GOOSE_MODEL and GOOSE_PROVIDER as priority.' | ||
| ); | ||
| await initializeSystem(config.GOOSE_PROVIDER, config.GOOSE_MODEL); | ||
| return; | ||
| } | ||
| const storedProvider = getStoredProvider(config); | ||
| const storedModel = getStoredModel(); | ||
| if (storedProvider) { | ||
| try { | ||
| await initializeSystem(storedProvider, storedModel); | ||
|
|
||
| if (!storedModel) { | ||
| const modelName = getDefaultModel(storedProvider.toLowerCase()); | ||
| const model = createSelectedModel(storedProvider.toLowerCase(), modelName); | ||
| switchModel(model); | ||
| addRecentModel(model); | ||
| } | ||
| } catch (error) { | ||
| // TODO: add sessionError state and show error screen with option to start fresh | ||
| console.error('Failed to initialize with stored provider:', error); | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| setupStoredProvider(); | ||
| }, []); | ||
|
|
||
| const { chat, setChat } = useChat({ setView, setIsLoadingSession }); | ||
|
|
||
| useEffect(() => { | ||
| const handleFatalError = (_: any, errorMessage: string) => { | ||
| setFatalError(errorMessage); | ||
| }; | ||
|
|
||
|
|
@@ -220,6 +177,26 @@ | |
| } | ||
| }, [view]); | ||
|
|
||
| // TODO: modify | ||
| useEffect(() => { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same function as before, just moved |
||
| const handleAddExtension = (_: any, link: string) => { | ||
| const command = extractCommand(link); | ||
| const extName = extractExtensionName(link); | ||
| window.electron.logInfo(`Adding extension from deep link ${link}`); | ||
| setPendingLink(link); | ||
| setModalMessage( | ||
| `Are you sure you want to install the ${extName} extension?\n\nCommand: ${command}` | ||
| ); | ||
| setModalVisible(true); | ||
| }; | ||
|
|
||
| window.electron.on('add-extension', handleAddExtension); | ||
| return () => { | ||
| window.electron.off('add-extension', handleAddExtension); | ||
| }; | ||
| }, []); | ||
|
|
||
| // TODO: modify | ||
| const handleConfirm = async () => { | ||
| if (pendingLink && !isInstalling) { | ||
| setIsInstalling(true); | ||
|
|
@@ -235,12 +212,68 @@ | |
| } | ||
| }; | ||
|
|
||
| // TODO: modify | ||
| const handleCancel = () => { | ||
| console.log('Cancelled extension installation.'); | ||
| setModalVisible(false); | ||
| setPendingLink(null); | ||
| }; | ||
|
|
||
| const { switchModel } = useModel(); // TODO: remove | ||
| const { addRecentModel } = useRecentModels(); // TODO: remove | ||
|
|
||
|
Comment on lines
+222
to
+224
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as before just moved |
||
| useEffect(() => { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. new conditional hook -- the old process for starting the app and getting the state of the providers is here |
||
| if (process.env.ALPHA) { | ||
| return; | ||
| } | ||
|
|
||
| // TODO: remove | ||
| // Attempt to detect config for a stored provider | ||
| const detectStoredProvider = () => { | ||
| const config = window.electron.getConfig(); | ||
| const storedProvider = getStoredProvider(config); | ||
| if (storedProvider) { | ||
| setView('chat'); | ||
| } else { | ||
| setView('welcome'); | ||
| } | ||
| }; | ||
|
|
||
| // TODO: remove | ||
| // Initialize system if we have a stored provider | ||
| const setupStoredProvider = async () => { | ||
| const config = window.electron.getConfig(); | ||
|
|
||
| if (config.GOOSE_PROVIDER && config.GOOSE_MODEL) { | ||
| window.electron.logInfo( | ||
| 'Initializing system with environment: GOOSE_MODEL and GOOSE_PROVIDER as priority.' | ||
| ); | ||
| await initializeSystem(config.GOOSE_PROVIDER, config.GOOSE_MODEL); | ||
| return; | ||
| } | ||
| const storedProvider = getStoredProvider(config); | ||
| const storedModel = getStoredModel(); | ||
| if (storedProvider) { | ||
| try { | ||
| await initializeSystem(storedProvider, storedModel); | ||
|
|
||
| if (!storedModel) { | ||
| const modelName = getDefaultModel(storedProvider.toLowerCase()); | ||
| const model = createSelectedModel(storedProvider.toLowerCase(), modelName); | ||
| switchModel(model); | ||
| addRecentModel(model); | ||
| } | ||
| } catch (error) { | ||
| // TODO: add sessionError state and show error screen with option to start fresh | ||
| console.error('Failed to initialize with stored provider:', error); | ||
| } | ||
| } | ||
| }; | ||
| detectStoredProvider(); | ||
| setupStoredProvider(); | ||
| }, []); | ||
|
|
||
| // keep | ||
| if (fatalError) { | ||
| return <ErrorScreen error={fatalError} onReload={() => window.electron.reloadApp()} />; | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just moved from below