Add session to agents (#4216)

Co-authored-by: Douwe Osinga <douwe@squareup.com>
Co-authored-by: Jack Amadeo <jackamadeo@squareup.com>
Co-authored-by: Jack Amadeo <jackamadeo@block.xyz>
This commit is contained in:
Douwe Osinga
2025-09-03 10:31:24 -04:00
committed by GitHub
parent db94c5b7c3
commit d2195289cf
65 changed files with 1473 additions and 1601 deletions
@@ -11,7 +11,7 @@ import {
LoaderCircle,
AlertCircle,
} from 'lucide-react';
import { type SessionDetails } from '../../sessions';
import { resumeSession, type SessionDetails } from '../../sessions';
import { Button } from '../ui/button';
import { toast } from 'react-toastify';
import { MainPanelLayout } from '../Layout/MainPanelLayout';
@@ -38,10 +38,7 @@ const isUserMessage = (message: Message): boolean => {
if (message.role === 'assistant') {
return false;
}
if (message.content.every((c) => c.type === 'toolConfirmationRequest')) {
return false;
}
return true;
return !message.content.every((c) => c.type === 'toolConfirmationRequest');
};
const filterMessagesForDisplay = (messages: Message[]): Message[] => {
@@ -112,7 +109,7 @@ const SessionMessages: React.FC<{
<ProgressiveMessageList
messages={filteredMessages}
chat={{
id: 'session-preview',
sessionId: 'session-preview',
messageHistoryIndex: filteredMessages.length,
}}
toolCallNotifications={new Map()}
@@ -189,7 +186,7 @@ const SessionHistoryView: React.FC<SessionHistoryViewProps> = ({
session.metadata.working_dir,
session.messages,
session.metadata.description || 'Shared Session',
session.metadata.total_tokens
session.metadata.total_tokens || 0
);
const shareableLink = `goose://sessions/${shareToken}`;
@@ -219,31 +216,10 @@ const SessionHistoryView: React.FC<SessionHistoryViewProps> = ({
};
const handleLaunchInNewWindow = () => {
if (session) {
console.log('Launching session in new window:', session.session_id);
console.log('Session details:', session);
// Get the working directory from the session metadata
const workingDir = session.metadata?.working_dir;
if (workingDir) {
console.log(
`Opening new window with session ID: ${session.session_id}, in working dir: ${workingDir}`
);
// Create a new chat window with the working directory and session ID
window.electron.createChatWindow(
undefined, // query
workingDir, // dir
undefined, // version
session.session_id // resumeSessionId
);
console.log('createChatWindow called successfully');
} else {
console.error('No working directory found in session metadata');
toast.error('Could not launch session: Missing working directory');
}
try {
resumeSession(session);
} catch (error) {
toast.error(`Could not launch session: ${error instanceof Error ? error.message : error}`);
}
};
@@ -312,7 +288,7 @@ const SessionHistoryView: React.FC<SessionHistoryViewProps> = ({
{session.metadata.total_tokens !== null && (
<span className="flex items-center">
<Target className="w-4 h-4 mr-1" />
{session.metadata.total_tokens.toLocaleString()}
{(session.metadata.total_tokens || 0).toLocaleString()}
</span>
)}
</div>
@@ -413,7 +413,7 @@ const SessionListView: React.FC<SessionListViewProps> = React.memo(
<div className="flex items-center">
<Target className="w-3 h-3 mr-1" />
<span className="font-mono">
{session.metadata.total_tokens.toLocaleString()}
{(session.metadata.total_tokens || 0).toLocaleString()}
</span>
</div>
)}
@@ -2,7 +2,7 @@ import { useEffect, useState } from 'react';
import { Card, CardContent, CardDescription } from '../ui/card';
import { getApiUrl } from '../../config';
import { Greeting } from '../common/Greeting';
import { fetchSessions, fetchSessionDetails, type Session } from '../../sessions';
import { fetchSessions, type Session, resumeSession } from '../../sessions';
import { useNavigate } from 'react-router-dom';
import { Button } from '../ui/button';
import { ChatSmart } from '../icons/';
@@ -104,21 +104,13 @@ export function SessionInsights() {
};
}, []);
const handleSessionClick = async (sessionId: string) => {
const handleSessionClick = async (session: Session) => {
try {
// Fetch the session details
const sessionDetails = await fetchSessionDetails(sessionId);
// Navigate to pair view with the resumed session
navigate('/pair', {
state: { resumedSession: sessionDetails },
replace: true,
});
resumeSession(session);
} catch (error) {
console.error('Failed to load session:', error);
// Fallback to the sessions view if loading fails
console.error('Failed to start session:', error);
navigate('/sessions', {
state: { selectedSessionId: sessionId },
state: { selectedSessionId: session.id },
replace: true,
});
}
@@ -358,13 +350,13 @@ export function SessionInsights() {
<div
key={session.id}
className="flex items-center justify-between text-sm py-1 px-2 rounded-md hover:bg-background-muted cursor-pointer transition-colors session-item"
onClick={() => handleSessionClick(session.id)}
onClick={() => handleSessionClick(session)}
role="button"
tabIndex={0}
style={{ animationDelay: `${index * 0.1}s` }}
onKeyDown={async (e) => {
if (e.key === 'Enter' || e.key === ' ') {
await handleSessionClick(session.id);
await handleSessionClick(session);
}
}}
>
@@ -68,7 +68,7 @@ const SessionsView: React.FC<SessionsViewProps> = ({ setView }) => {
const handleRetryLoadSession = () => {
if (selectedSession) {
loadSessionDetails(selectedSession.session_id);
loadSessionDetails(selectedSession.sessionId);
}
};
@@ -78,7 +78,7 @@ const SessionsView: React.FC<SessionsViewProps> = ({ setView }) => {
<SessionHistoryView
session={
selectedSession || {
session_id: initialSessionId || '',
sessionId: initialSessionId || '',
messages: [],
metadata: {
description: 'Loading...',
@@ -97,7 +97,7 @@ const SessionsView: React.FC<SessionsViewProps> = ({ setView }) => {
<SessionListView
setView={setView}
onSelectSession={handleSelectSession}
selectedSessionId={selectedSession?.session_id ?? null}
selectedSessionId={selectedSession?.sessionId ?? null}
/>
);
};