diff --git a/ui/desktop/src/components/SessionPIlls.tsx b/ui/desktop/src/components/SessionPIlls.tsx
deleted file mode 100644
index 647a88425..000000000
--- a/ui/desktop/src/components/SessionPIlls.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import React, { useEffect, useState } from "react"
-
-export default function SessionPills() {
- const [sessions, setSessions] = useState([]);
- const [latestSessions, setLatestSessions] = useState([]);
-
- const workingDir = window.appConfig.get("GOOSE_WORKING_DIR");
-
- useEffect(() => {
- async function loadSessions() {
- window.electron.logInfo(`_------______________ Looking for sessions related to ${workingDir}`);
- const sessions = await window.electron.listSessions(workingDir);
-
- window.electron.logInfo(`_------______________ Found ${sessions.length} sessions in ${workingDir}`);
- window.electron.logInfo(`Sessions: ${JSON.stringify(sessions)}`);
- setSessions(sessions);
- };
- loadSessions();
- }, []);
-
- useEffect(() => {
- async function loadSessions() {
- const sessions = await window.electron.listSessions();
- setLatestSessions(sessions);
- };
- loadSessions();
- }, []);
-
- if (sessions.length === 0 && latestSessions.length === 0) {
- return null;
- }
-
- // Create a combined list of sessions, prioritizing latest ones and removing duplicates
- const combinedSessions = [];
- const seenNames = new Set();
-
- // Add at least one latest session if available
- if (latestSessions.length > 0) {
- const latest = latestSessions[0];
- combinedSessions.push({ ...latest, isLatest: true });
- seenNames.add(latest.name);
- }
-
- // Add remaining latest sessions (up to 5 total)
- for (let i = 1; i < latestSessions.length && combinedSessions.length < 5; i++) {
- const session = latestSessions[i];
- if (!seenNames.has(session.name)) {
- combinedSessions.push({ ...session, isLatest: true });
- seenNames.add(session.name);
- }
- }
-
- // Fill remaining slots with regular sessions (up to 5 total)
- for (const session of sessions) {
- if (combinedSessions.length >= 5) break;
- if (!seenNames.has(session.name)) {
- combinedSessions.push({ ...session, isLatest: false });
- seenNames.add(session.name);
- }
- }
-
- return (
-
-
- {combinedSessions.map((session) => (
-
{
- window.electron.createChatWindow(undefined, session.directory, session.name);
- }}
- title={session.directory}>
-
- {`${session.name.slice(0, 50)}`}
- {session.isLatest && !(session.directory === workingDir) && (
- (recent)
- )}
-
- ))}
-
-
- )
-}
\ No newline at end of file
diff --git a/ui/desktop/src/components/SessionPills.tsx b/ui/desktop/src/components/SessionPills.tsx
new file mode 100644
index 000000000..c95eb01f9
--- /dev/null
+++ b/ui/desktop/src/components/SessionPills.tsx
@@ -0,0 +1,85 @@
+import React, { useEffect, useState } from "react"
+
+const useCombinedSessions = (workingDir: string) => {
+ const [sessions, setSessions] = useState([]);
+ const [latestSessions, setLatestSessions] = useState([]);
+
+ useEffect(() => {
+ async function loadSessions() {
+ const sessions = await window.electron.listSessions(workingDir);
+ setSessions(sessions);
+ const latestSessions = await window.electron.listSessions();
+ setLatestSessions(latestSessions);
+ };
+ loadSessions();
+ }, [workingDir]);
+
+ const getCombinedSessions = () => {
+ if (sessions.length === 0 && latestSessions.length === 0) {
+ return [];
+ }
+
+ const combinedSessions = [];
+ const seenNames = new Set();
+
+ // Add at least one latest session if available
+ if (latestSessions.length > 0) {
+ const latest = latestSessions[0];
+ combinedSessions.push({ ...latest, isLatest: true });
+ seenNames.add(latest.name);
+ }
+
+ // Add remaining latest sessions (up to 5 total)
+ for (let i = 1; i < latestSessions.length && combinedSessions.length < 5; i++) {
+ const session = latestSessions[i];
+ if (!seenNames.has(session.name)) {
+ combinedSessions.push({ ...session, isLatest: true });
+ seenNames.add(session.name);
+ }
+ }
+
+ // Fill remaining slots with regular sessions (up to 5 total)
+ for (const session of sessions) {
+ if (combinedSessions.length >= 5) break;
+ if (!seenNames.has(session.name)) {
+ combinedSessions.push({ ...session, isLatest: false });
+ seenNames.add(session.name);
+ }
+ }
+
+ return combinedSessions;
+ };
+
+ return getCombinedSessions();
+};
+
+export default function SessionPills() {
+ const workingDir = window.appConfig.get("GOOSE_WORKING_DIR");
+ const combinedSessions = useCombinedSessions(workingDir);
+
+ if (combinedSessions.length === 0) {
+ return null;
+ }
+
+ return (
+
+
+ {combinedSessions.map((session) => (
+
{
+ window.electron.createChatWindow(undefined, session.directory, session.name);
+ }}
+ title={session.directory}
+ >
+ {`${session.name.slice(0, 50)}`}
+ {session.isLatest && !(session.directory === workingDir) && (
+ (recent)
+ )}
+
+ ))}
+
+
+ )
+}
\ No newline at end of file
diff --git a/ui/desktop/src/components/Splash.tsx b/ui/desktop/src/components/Splash.tsx
index 071081002..10dc19326 100644
--- a/ui/desktop/src/components/Splash.tsx
+++ b/ui/desktop/src/components/Splash.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import GooseSplashLogo from './GooseSplashLogo';
import SplashPills from './SplashPills';
-import SessionPills from './SessionPIlls';
+import SessionPills from './SessionPills';
export default function Splash({ append }) {
diff --git a/ui/desktop/src/utils/sessionManager.ts b/ui/desktop/src/utils/sessionManager.ts
index 4572b9466..9b048ded6 100644
--- a/ui/desktop/src/utils/sessionManager.ts
+++ b/ui/desktop/src/utils/sessionManager.ts
@@ -4,123 +4,123 @@ import { app } from 'electron';
const SESSIONS_PATH = path.join(app.getPath('userData'), 'sessions');
if (!fs.existsSync(SESSIONS_PATH)) {
- fs.mkdirSync(SESSIONS_PATH);
+ fs.mkdirSync(SESSIONS_PATH);
}
interface Session {
- name: string; // Derived from a synopsis of the conversation
- messages: Array<{
- id: number;
- role: 'function' | 'system' | 'user' | 'assistant' | 'data' | 'tool';
- content: string;
- }>;
- directory: string;
+ name: string; // Derived from a synopsis of the conversation
+ messages: Array<{
+ id: number;
+ role: 'function' | 'system' | 'user' | 'assistant' | 'data' | 'tool';
+ content: string;
+ }>;
+ directory: string;
}
function generateSessionName(messages: {id: number, role: string, content: string}[]): string {
- // Create a session name based on the first message or a combination of initial messages
- if (messages === undefined || messages.length === 0) return 'empty_session';
- return messages[0].content.split(' ').slice(0, 5).join(' ');
+ // Create a session name based on the first message or a combination of initial messages
+ if (messages === undefined || messages.length === 0) return 'empty_session';
+ return messages[0].content.split(' ').slice(0, 5).join(' ');
}
function createSafeFilename(name: string): string {
- // Replace unsafe characters with underscores and limit length
- return name
- .replace(/[^a-zA-Z0-9-_]/g, '_') // Replace unsafe chars with underscore
- .replace(/_{2,}/g, '_') // Replace multiple underscores with single
- .replace(/^_|_$/g, '') // Remove leading/trailing underscores
- .substring(0, 100); // Limit length to 100 chars
+ // Replace unsafe characters with underscores and limit length
+ return name
+ .replace(/[^a-zA-Z0-9-_]/g, '_') // Replace unsafe chars with underscore
+ .replace(/_{2,}/g, '_') // Replace multiple underscores with single
+ .replace(/^_|_$/g, '') // Remove leading/trailing underscores
+ .substring(0, 100); // Limit length to 100 chars
}
export function saveSession(session: Session): string {
- try {
- const sessionData = {
- ...session,
- name: generateSessionName(session.messages)
- };
- const safeFileName = createSafeFilename(sessionData.name);
- const filePath = path.join(SESSIONS_PATH, `${safeFileName}.json`);
- fs.writeFileSync(filePath, JSON.stringify(sessionData, null, 2));
- console.log('Session saved:', sessionData);
- return sessionData.name;
- } catch (error) {
- console.error('Error saving session:', error);
- }
+ try {
+ const sessionData = {
+ ...session,
+ name: generateSessionName(session.messages)
+ };
+ const safeFileName = createSafeFilename(sessionData.name);
+ const filePath = path.join(SESSIONS_PATH, `${safeFileName}.json`);
+ fs.writeFileSync(filePath, JSON.stringify(sessionData, null, 2));
+ console.log('Session saved:', sessionData);
+ return sessionData.name;
+ } catch (error) {
+ console.error('Error saving session:', error);
+ }
}
export function loadSession(sessionId: string): Session | undefined {
- try {
- const safeFileName = createSafeFilename(sessionId);
- const filePath = path.join(SESSIONS_PATH, `${safeFileName}.json`);
- if (!fs.existsSync(filePath)) {
- console.warn('Session file not found:', sessionId);
- return undefined;
- }
- const data = fs.readFileSync(filePath, 'utf8');
- const session = JSON.parse(data) as Session;
- console.log('Session loaded:', session);
- return session;
- } catch (error) {
- console.error('Error loading session:', error);
+ try {
+ const safeFileName = createSafeFilename(sessionId);
+ const filePath = path.join(SESSIONS_PATH, `${safeFileName}.json`);
+ if (!fs.existsSync(filePath)) {
+ console.warn('Session file not found:', sessionId);
+ return undefined;
}
+ const data = fs.readFileSync(filePath, 'utf8');
+ const session = JSON.parse(data) as Session;
+ console.log('Session loaded:', session);
+ return session;
+ } catch (error) {
+ console.error('Error loading session:', error);
+ }
}
// load sessions that are relevant to the directory supplied (not where they are stored, but where user is operating)
export function loadSessions(dir?: string): Session[] {
- try {
- console.log('Attempting to load sessions from:', SESSIONS_PATH);
- const MAX_AGE_DAYS = 10;
- // Get the current date
- const now = Date.now();
- const maxAgeMs = MAX_AGE_DAYS * 24 * 60 * 60 * 1000;
+ try {
+ console.log('Attempting to load sessions from:', SESSIONS_PATH);
+ const MAX_AGE_DAYS = 10;
+ // Get the current date
+ const now = Date.now();
+ const maxAgeMs = MAX_AGE_DAYS * 24 * 60 * 60 * 1000;
- // Get all files in the directory
- const files = fs.readdirSync(SESSIONS_PATH);
+ // Get all files in the directory
+ const files = fs.readdirSync(SESSIONS_PATH);
- if (files.length === 0) {
- console.warn('No session files found in directory');
- return [];
- }
+ if (files.length === 0) {
+ console.warn('No session files found in directory');
+ return [];
+ }
- // Filter files based on their age and limit to max 100 files
- const filteredFiles = files
- .map(file => {
- const filePath = path.join(SESSIONS_PATH, file);
- const stats = fs.statSync(filePath);
- const age = now - stats.mtimeMs;
- return { file, age };
- })
- .filter(({ age }) => age <= maxAgeMs);
+ // Filter files based on their age and limit to max 100 files
+ const filteredFiles = files
+ .map(file => {
+ const filePath = path.join(SESSIONS_PATH, file);
+ const stats = fs.statSync(filePath);
+ const age = now - stats.mtimeMs;
+ return { file, age };
+ })
+ .filter(({ age }) => age <= maxAgeMs);
- if (filteredFiles.length === 0) {
- console.warn('No session files meet the age criteria');
- return [];
- }
+ if (filteredFiles.length === 0) {
+ console.warn('No session files meet the age criteria');
+ return [];
+ }
- // Load the filtered files and parse them into sessions
- const sessions = filteredFiles.map(({ file }) => {
- const data = fs.readFileSync(path.join(SESSIONS_PATH, file), 'utf8');
- return JSON.parse(data) as Session;
- });
- if (dir) {
- // Filter sessions based on the directory
- return sessions.filter(session => session.directory === dir).splice(0, 4);
- } else {
- // just recent sessions
- return sessions.splice(0, 20);
- }
- } catch (error) {
- console.error('Error loading sessions:', error);
- return [];
+ // Load the filtered files and parse them into sessions
+ const sessions = filteredFiles.map(({ file }) => {
+ const data = fs.readFileSync(path.join(SESSIONS_PATH, file), 'utf8');
+ return JSON.parse(data) as Session;
+ });
+ if (dir) {
+ // Filter sessions based on the directory
+ return sessions.filter(session => session.directory === dir).splice(0, 4);
+ } else {
+ // just recent sessions
+ return sessions.splice(0, 20);
}
+ } catch (error) {
+ console.error('Error loading sessions:', error);
+ return [];
+ }
}
export function clearAllSessions(): void {
- try {
- const files = fs.readdirSync(SESSIONS_PATH);
- files.forEach(file => fs.unlinkSync(path.join(SESSIONS_PATH, file)));
- console.log('All sessions cleared');
- } catch (error) {
- console.error('Error clearing sessions:', error);
- }
+ try {
+ const files = fs.readdirSync(SESSIONS_PATH);
+ files.forEach(file => fs.unlinkSync(path.join(SESSIONS_PATH, file)));
+ console.log('All sessions cleared');
+ } catch (error) {
+ console.error('Error clearing sessions:', error);
+ }
}
\ No newline at end of file