ui: add logs to app (#1760)

This commit is contained in:
Lily Delalande
2025-03-19 14:55:11 -04:00
committed by GitHub
parent d14e5f4de7
commit 15f6973bcf
2 changed files with 152 additions and 49 deletions

View File

@@ -73,62 +73,107 @@ export default function App() {
return `${cmd} ${args.join(' ')}`.trim();
}
// this is all settings v2 stuff
useEffect(() => {
// Skip if feature flag is not enabled
if (!process.env.ALPHA) {
return;
}
console.log('Alpha flow initializing...');
const setupExtensions = async () => {
try {
console.log('Setting up extensions...');
// Set the ref immediately to prevent duplicate runs
initAttemptedRef.current = true;
console.log('Set initAttemptedRef to prevent duplicate runs');
// Force refresh extensions from the backend to ensure we have the latest
console.log('Getting extensions from backend...');
const refreshedExtensions = await getExtensions(true);
console.log(`Retrieved ${refreshedExtensions.length} extensions`);
if (refreshedExtensions.length === 0) {
// If we still have no extensions, this is truly a first-time setup
console.log('First-time setup: Adding all built-in extensions...');
await initializeBuiltInExtensions(addExtension);
console.log('Built-in extensions initialization complete');
} else {
// Extensions exist, check for any missing built-ins
console.log('Checking for missing built-in extensions...');
console.log(refreshedExtensions);
console.log('Current extensions:', refreshedExtensions);
await syncBuiltInExtensions(refreshedExtensions, addExtension);
console.log('Built-in extensions sync complete');
}
} catch (error) {
console.error('Error setting up extensions:', error);
console.error('Extension setup error details:', {
message: error.message,
stack: error.stack,
name: error.name,
});
// We don't set fatal error here since the app might still work without extensions
}
};
const initializeApp = async () => {
try {
console.log('Initializing alpha app...');
// Check if we have the required configuration
console.log('Reading GOOSE_PROVIDER from config...');
const provider = (await read('GOOSE_PROVIDER', false)) as string;
console.log('Provider from config:', provider);
console.log('Reading GOOSE_MODEL from config...');
const model = (await read('GOOSE_MODEL', false)) as string;
console.log('Model from config:', model);
if (provider && model) {
// We have all needed configuration, initialize the system
console.log('Initializing system with stored GOOSE_MODEL and GOOSE_PROVIDER');
console.log(`Initializing system with provider: ${provider}, model: ${model}`);
await initializeSystem(provider, model);
console.log('System initialization successful');
setView('chat');
} else {
// Missing configuration, show onboarding
console.log('Missing configuration, showing onboarding');
if (!provider) console.log('Missing provider');
if (!model) console.log('Missing model');
setView('welcome');
}
} catch (error) {
console.error('Error initializing app:', error);
console.error('App initialization error details:', {
message: error.message,
stack: error.stack,
name: error.name,
});
setFatalError(`Alpha initialization error: ${error.message || 'Unknown error'}`);
setView('welcome');
}
};
initializeApp().then();
setupExtensions().then();
// Execute with better promise handling
initializeApp()
.then(() => console.log('Alpha app initialization complete'))
.catch((error) => {
console.error('Unhandled error in initializeApp:', error);
setFatalError(`Unhandled alpha app error: ${error.message || 'Unknown error'}`);
});
setupExtensions()
.then(() => console.log('Extensions setup complete'))
.catch((error) => {
console.error('Unhandled error in setupExtensions:', error);
// Not setting fatal error here since extensions are optional
});
}, []); // Empty dependency array since we're using initAttemptedRef
const setView = (view: View, viewOptions: Record<any, any> = {}) => {
console.log(`Setting view to: ${view}`, viewOptions);
setInternalView({ view, viewOptions });
};
@@ -136,14 +181,29 @@ export default function App() {
const [isLoadingSession, setIsLoadingSession] = useState(false);
const { chat, setChat } = useChat({ setView, setIsLoadingSession });
useEffect(() => window.electron.reactReady(), []);
useEffect(() => {
console.log('Sending reactReady signal to Electron');
try {
window.electron.reactReady();
} catch (error) {
console.error('Error sending reactReady:', error);
setFatalError(`React ready notification failed: ${error.message}`);
}
}, []);
// Keyboard shortcut handler
useEffect(() => {
console.log('Setting up keyboard shortcuts');
const handleKeyDown = (event: KeyboardEvent) => {
if ((event.metaKey || event.ctrlKey) && event.key === 'n') {
event.preventDefault();
window.electron.createChatWindow(undefined, window.appConfig.get('GOOSE_WORKING_DIR'));
try {
const workingDir = window.appConfig.get('GOOSE_WORKING_DIR');
console.log(`Creating new chat window with working dir: ${workingDir}`);
window.electron.createChatWindow(undefined, workingDir);
} catch (error) {
console.error('Error creating new window:', error);
}
}
};
@@ -154,7 +214,12 @@ export default function App() {
}, []);
useEffect(() => {
console.log('Setting up fatal error handler');
const handleFatalError = (_: any, errorMessage: string) => {
console.error('Encountered a fatal error: ', errorMessage);
// Log additional context that might help diagnose the issue
console.error('Current view:', view);
console.error('Is loading session:', isLoadingSession);
setFatalError(errorMessage);
};
@@ -162,32 +227,45 @@ export default function App() {
return () => {
window.electron.off('fatal-error', handleFatalError);
};
}, []);
}, [view, isLoadingSession]); // Add dependencies to provide context in error logs
useEffect(() => {
const handleSetView = (_, view) => setView(view);
console.log('Setting up view change handler');
const handleSetView = (_, newView) => {
console.log(`Received view change request to: ${newView}`);
setView(newView);
};
window.electron.on('set-view', handleSetView);
return () => window.electron.off('set-view', handleSetView);
}, []);
// Add cleanup for session states when view changes
useEffect(() => {
console.log(`View changed to: ${view}`);
if (view !== 'chat') {
console.log('Not in chat view, clearing loading session state');
setIsLoadingSession(false);
}
}, [view]);
// TODO: modify
useEffect(() => {
console.log('Setting up extension handler');
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);
try {
console.log(`Received add-extension event with link: ${link}`);
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);
} catch (error) {
console.error('Error handling add-extension event:', error);
}
};
window.electron.on('add-extension', handleAddExtension);
@@ -199,11 +277,14 @@ export default function App() {
// TODO: modify
const handleConfirm = async () => {
if (pendingLink && !isInstalling) {
console.log(`Confirming installation of extension from: ${pendingLink}`);
setIsInstalling(true);
try {
await addExtensionFromDeepLink(pendingLink, setView);
console.log('Extension installation successful');
} catch (error) {
console.error('Failed to add extension:', error);
// Consider showing a user-visible error notification here
} finally {
setModalVisible(false);
setPendingLink(null);
@@ -219,6 +300,7 @@ export default function App() {
setPendingLink(null);
};
// TODO: remove
const { switchModel } = useModel(); // TODO: remove
const { addRecentModel } = useRecentModels(); // TODO: remove
@@ -227,50 +309,71 @@ export default function App() {
return;
}
// TODO: remove
console.log('Non-alpha flow initializing...');
// 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');
try {
const config = window.electron.getConfig();
console.log('Loaded config:', JSON.stringify(config));
const storedProvider = getStoredProvider(config);
console.log('Stored provider:', storedProvider);
if (storedProvider) {
setView('chat');
} else {
setView('welcome');
}
} catch (err) {
console.error('DETECTION ERROR:', err);
setFatalError(`Config detection error: ${err.message || 'Unknown error'}`);
}
};
// TODO: remove
// Initialize system if we have a stored provider
const setupStoredProvider = async () => {
const config = window.electron.getConfig();
try {
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);
if (config.GOOSE_PROVIDER && config.GOOSE_MODEL) {
console.log('using GOOSE_PROVIDER and GOOSE_MODEL from config');
await initializeSystem(config.GOOSE_PROVIDER, config.GOOSE_MODEL);
return;
}
const storedProvider = getStoredProvider(config);
const storedModel = getStoredModel();
if (storedProvider) {
try {
await initializeSystem(storedProvider, storedModel);
console.log('Setup using locally stored provider:', storedProvider);
console.log('Setup using locally stored model:', storedModel);
if (!storedModel) {
const modelName = getDefaultModel(storedProvider.toLowerCase());
const model = createSelectedModel(storedProvider.toLowerCase(), modelName);
switchModel(model);
addRecentModel(model);
}
} catch (error) {
console.error('Failed to initialize with stored provider:', error);
setFatalError(`Initialization failed: ${error.message || 'Unknown error'}`);
}
}
} catch (err) {
console.error('SETUP ERROR:', err);
setFatalError(`Setup error: ${err.message || 'Unknown error'}`);
}
};
// Execute the functions with better error handling
detectStoredProvider();
setupStoredProvider();
setupStoredProvider().catch((err) => {
console.error('ASYNC SETUP ERROR:', err);
setFatalError(`Async setup error: ${err.message || 'Unknown error'}`);
});
}, []);
// keep