Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 112 additions & 79 deletions ui/desktop/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Check warning on line 14 in ui/desktop/src/App.tsx

View workflow job for this annotation

GitHub Actions / Lint Electron Desktop App

'fetchSessionDetails' is defined but never used. Allowed unused vars must match /^_/u

import WelcomeView from './components/WelcomeView';
import ChatView from './components/ChatView';
Expand Down Expand Up @@ -49,7 +49,7 @@
| {
resumedSession?: SessionDetails;
}
| Record<string, any>;

Check warning on line 52 in ui/desktop/src/App.tsx

View workflow job for this annotation

GitHub Actions / Lint Electron Desktop App

Unexpected any. Specify a different type
};

export default function App() {
Expand All @@ -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 {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just moved from below

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) {
Expand Down Expand Up @@ -94,46 +102,42 @@
}
};

setupExtensions();
}, []); // Empty dependency array since we're using initAttemptedRef
const initializeApp = async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The 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

Check warning on line 129 in ui/desktop/src/App.tsx

View workflow job for this annotation

GitHub Actions / Lint Electron Desktop App

React Hook useEffect has missing dependencies: 'addExtension', 'getExtensions', and 'read'. Either include them or remove the dependency array

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

View workflow job for this annotation

GitHub Actions / Lint Electron Desktop App

Unexpected any. Specify a different type

Check warning on line 131 in ui/desktop/src/App.tsx

View workflow job for this annotation

GitHub Actions / Lint Electron Desktop App

Unexpected any. Specify a different type
setInternalView({ view, viewOptions });
};

// Utility function to extract the command from the link
function extractCommand(link: string): string {
Copy link
Contributor Author

Choose a reason for hiding this comment

The 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(() => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The 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) => {
Expand All @@ -149,55 +153,8 @@
};
}, []);

// Attempt to detect config for a stored provider
useEffect(() => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved into separate hook below (ctrl+f for detectStoredProvider)

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(() => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved into conditional hook -- look for setupStoredProvider below

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) => {

Check warning on line 157 in ui/desktop/src/App.tsx

View workflow job for this annotation

GitHub Actions / Lint Electron Desktop App

Unexpected any. Specify a different type
setFatalError(errorMessage);
};

Expand All @@ -220,6 +177,26 @@
}
}, [view]);

// TODO: modify
useEffect(() => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same function as before, just moved

const handleAddExtension = (_: any, link: string) => {

Check warning on line 182 in ui/desktop/src/App.tsx

View workflow job for this annotation

GitHub Actions / Lint Electron Desktop App

Unexpected any. Specify a different type
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);
Expand All @@ -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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as before just moved

useEffect(() => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The 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();
}, []);

Check warning on line 274 in ui/desktop/src/App.tsx

View workflow job for this annotation

GitHub Actions / Lint Electron Desktop App

React Hook useEffect has missing dependencies: 'addRecentModel' and 'switchModel'. Either include them or remove the dependency array

// keep
if (fatalError) {
return <ErrorScreen error={fatalError} onReload={() => window.electron.reloadApp()} />;
}
Expand Down
Loading