diff --git a/ui/desktop/src/App.tsx b/ui/desktop/src/App.tsx index c87aa5a1977d..1f63e9b2f3ae 100644 --- a/ui/desktop/src/App.tsx +++ b/ui/desktop/src/App.tsx @@ -62,9 +62,17 @@ export default function App() { 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 @@ export default function App() { } }; - setupExtensions(); - }, []); // Empty dependency array since we're using initAttemptedRef + const initializeApp = async () => { + 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 = {}) => { setInternalView({ view, viewOptions }); }; - // 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(); - } + const [isGoosehintsModalOpen, setIsGoosehintsModalOpen] = useState(false); + const [isLoadingSession, setIsLoadingSession] = useState(false); + const { chat, setChat } = useChat({ setView, setIsLoadingSession }); useEffect(() => window.electron.reactReady(), []); - useEffect(() => { - 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,53 +153,6 @@ export default function App() { }; }, []); - // Attempt to detect config for a stored provider - useEffect(() => { - 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(() => { - 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 @@ export default function App() { } }, [view]); + // TODO: modify + useEffect(() => { + 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 @@ export default function App() { } }; + // TODO: modify const handleCancel = () => { console.log('Cancelled extension installation.'); setModalVisible(false); setPendingLink(null); }; + const { switchModel } = useModel(); // TODO: remove + const { addRecentModel } = useRecentModels(); // TODO: remove + + useEffect(() => { + 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 window.electron.reloadApp()} />; }