Include Session ID appropriately in UI (#4901)

This commit is contained in:
tlongwell-block
2025-10-01 12:35:24 -04:00
committed by GitHub
parent 3b9a3b96c5
commit 5bf698cc50
6 changed files with 44 additions and 20 deletions
+17 -3
View File
@@ -357,10 +357,12 @@ export function AppInner() {
if (loadingHub) { if (loadingHub) {
(async () => { (async () => {
try { try {
await loadCurrentChat({ const loadedChat = await loadCurrentChat({
setAgentWaitingMessage, setAgentWaitingMessage,
setIsExtensionsLoading, setIsExtensionsLoading,
}); });
// Update the chat state with the loaded session to ensure sessionId is available globally
setChat(loadedChat);
} catch (e) { } catch (e) {
if (e instanceof NoProviderOrModelError) { if (e instanceof NoProviderOrModelError) {
// the onboarding flow will trigger // the onboarding flow will trigger
@@ -370,7 +372,7 @@ export function AppInner() {
} }
})(); })();
} }
}, [resetChat, loadCurrentChat, setAgentWaitingMessage, navigate, loadingHub]); }, [resetChat, loadCurrentChat, setAgentWaitingMessage, navigate, loadingHub, setChat]);
useEffect(() => { useEffect(() => {
const handleOpenSharedSession = async (_event: IpcRendererEvent, ...args: unknown[]) => { const handleOpenSharedSession = async (_event: IpcRendererEvent, ...args: unknown[]) => {
@@ -582,7 +584,19 @@ export function AppInner() {
} }
/> />
<Route path="settings" element={<SettingsRoute />} /> <Route path="settings" element={<SettingsRoute />} />
<Route path="extensions" element={<ExtensionsRoute />} /> <Route
path="extensions"
element={
<ChatProvider
chat={chat}
setChat={setChat}
contextKey="extensions"
agentWaitingMessage={agentWaitingMessage}
>
<ExtensionsRoute />
</ChatProvider>
}
/>
<Route path="sessions" element={<SessionsRoute />} /> <Route path="sessions" element={<SessionsRoute />} />
<Route path="schedules" element={<SchedulesRoute />} /> <Route path="schedules" element={<SchedulesRoute />} />
<Route path="recipes" element={<RecipesRoute />} /> <Route path="recipes" element={<RecipesRoute />} />
+1 -1
View File
@@ -441,7 +441,7 @@ function BaseChatContent({
onClick={async () => { onClick={async () => {
clearError(); clearError();
await handleManualCompaction(messages, setMessages, append); await handleManualCompaction(messages, setMessages, append, chat.sessionId);
}} }}
> >
Summarize Conversation Summarize Conversation
+1 -1
View File
@@ -568,7 +568,7 @@ export default function ChatInput({
// Hide the alert popup by dispatching a custom event that the popover can listen to // Hide the alert popup by dispatching a custom event that the popover can listen to
// Importantly, this leaves the alert so the dot still shows up, but hides the popover // Importantly, this leaves the alert so the dot still shows up, but hides the popover
window.dispatchEvent(new CustomEvent('hide-alert-popover')); window.dispatchEvent(new CustomEvent('hide-alert-popover'));
handleManualCompaction(messages, setMessages, append); handleManualCompaction(messages, setMessages, append, sessionId || '');
}, },
compactIcon: <ScrollText size={12} />, compactIcon: <ScrollText size={12} />,
autoCompactThreshold: autoCompactThreshold, autoCompactThreshold: autoCompactThreshold,
@@ -12,12 +12,14 @@ interface ContextManagerActions {
handleAutoCompaction: ( handleAutoCompaction: (
messages: Message[], messages: Message[],
setMessages: (messages: Message[]) => void, setMessages: (messages: Message[]) => void,
append: (message: Message) => void append: (message: Message) => void,
sessionId: string
) => Promise<void>; ) => Promise<void>;
handleManualCompaction: ( handleManualCompaction: (
messages: Message[], messages: Message[],
setMessages: (messages: Message[]) => void, setMessages: (messages: Message[]) => void,
append?: (message: Message) => void append?: (message: Message) => void,
sessionId?: string
) => Promise<void>; ) => Promise<void>;
hasCompactionMarker: (message: Message) => boolean; hasCompactionMarker: (message: Message) => boolean;
} }
@@ -37,6 +39,7 @@ export const ContextManagerProvider: React.FC<{ children: React.ReactNode }> = (
messages: Message[], messages: Message[],
setMessages: (messages: Message[]) => void, setMessages: (messages: Message[]) => void,
append: (message: Message) => void, append: (message: Message) => void,
sessionId: string,
isManual: boolean = false isManual: boolean = false
) => { ) => {
setIsCompacting(true); setIsCompacting(true);
@@ -47,6 +50,7 @@ export const ContextManagerProvider: React.FC<{ children: React.ReactNode }> = (
const summaryResponse = await manageContextFromBackend({ const summaryResponse = await manageContextFromBackend({
messages: messages, messages: messages,
manageAction: 'summarize', manageAction: 'summarize',
sessionId: sessionId,
}); });
// Convert API messages to frontend messages // Convert API messages to frontend messages
@@ -100,9 +104,10 @@ export const ContextManagerProvider: React.FC<{ children: React.ReactNode }> = (
async ( async (
messages: Message[], messages: Message[],
setMessages: (messages: Message[]) => void, setMessages: (messages: Message[]) => void,
append: (message: Message) => void append: (message: Message) => void,
sessionId: string
) => { ) => {
await performCompaction(messages, setMessages, append, false); await performCompaction(messages, setMessages, append, sessionId, false);
}, },
[performCompaction] [performCompaction]
); );
@@ -111,9 +116,10 @@ export const ContextManagerProvider: React.FC<{ children: React.ReactNode }> = (
async ( async (
messages: Message[], messages: Message[],
setMessages: (messages: Message[]) => void, setMessages: (messages: Message[]) => void,
append?: (message: Message) => void append?: (message: Message) => void,
sessionId?: string
) => { ) => {
await performCompaction(messages, setMessages, append || (() => {}), true); await performCompaction(messages, setMessages, append || (() => {}), sessionId || '', true);
}, },
[performCompaction] [performCompaction]
); );
@@ -166,12 +166,13 @@ describe('ContextManager', () => {
const { result } = renderContextManager(); const { result } = renderContextManager();
await act(async () => { await act(async () => {
await result.current.handleAutoCompaction(mockMessages, mockSetMessages, mockAppend); await result.current.handleAutoCompaction(mockMessages, mockSetMessages, mockAppend, 'test-session-id');
}); });
expect(mockManageContextFromBackend).toHaveBeenCalledWith({ expect(mockManageContextFromBackend).toHaveBeenCalledWith({
messages: mockMessages, messages: mockMessages,
manageAction: 'summarize', manageAction: 'summarize',
sessionId: 'test-session-id',
}); });
// Verify conversion calls with correct parameters // Verify conversion calls with correct parameters
@@ -225,7 +226,7 @@ describe('ContextManager', () => {
const { result } = renderContextManager(); const { result } = renderContextManager();
await act(async () => { await act(async () => {
await result.current.handleAutoCompaction(mockMessages, mockSetMessages, mockAppend); await result.current.handleAutoCompaction(mockMessages, mockSetMessages, mockAppend, "test-session-id");
}); });
expect(result.current.compactionError).toBe('Backend error'); expect(result.current.compactionError).toBe('Backend error');
@@ -256,7 +257,7 @@ describe('ContextManager', () => {
// Start compaction // Start compaction
act(() => { act(() => {
result.current.handleAutoCompaction(mockMessages, mockSetMessages, mockAppend); result.current.handleAutoCompaction(mockMessages, mockSetMessages, mockAppend, "test-session-id");
}); });
// Should be compacting // Should be compacting
@@ -306,7 +307,7 @@ describe('ContextManager', () => {
const { result } = renderContextManager(); const { result } = renderContextManager();
await act(async () => { await act(async () => {
await result.current.handleAutoCompaction(messages, mockSetMessages, mockAppend); await result.current.handleAutoCompaction(messages, mockSetMessages, mockAppend, "test-session-id");
}); });
// No server messages -> setMessages called with empty list // No server messages -> setMessages called with empty list
@@ -369,12 +370,13 @@ describe('ContextManager', () => {
const { result } = renderContextManager(); const { result } = renderContextManager();
await act(async () => { await act(async () => {
await result.current.handleManualCompaction(mockMessages, mockSetMessages, mockAppend); await result.current.handleManualCompaction(mockMessages, mockSetMessages, mockAppend, 'test-session-id');
}); });
expect(mockManageContextFromBackend).toHaveBeenCalledWith({ expect(mockManageContextFromBackend).toHaveBeenCalledWith({
messages: mockMessages, messages: mockMessages,
manageAction: 'summarize', manageAction: 'summarize',
sessionId: 'test-session-id',
}); });
// Verify all three messages are set // Verify all three messages are set
@@ -481,7 +483,7 @@ describe('ContextManager', () => {
const { result } = renderContextManager(); const { result } = renderContextManager();
await act(async () => { await act(async () => {
await result.current.handleManualCompaction(mockMessages, mockSetMessages, mockAppend); await result.current.handleManualCompaction(mockMessages, mockSetMessages, mockAppend, 'test-session-id');
}); });
// Verify all three messages are set // Verify all three messages are set
@@ -508,7 +510,7 @@ describe('ContextManager', () => {
const { result } = renderContextManager(); const { result } = renderContextManager();
await act(async () => { await act(async () => {
await result.current.handleAutoCompaction(mockMessages, mockSetMessages, mockAppend); await result.current.handleAutoCompaction(mockMessages, mockSetMessages, mockAppend, "test-session-id");
}); });
expect(result.current.compactionError).toBe('Unknown error during compaction'); expect(result.current.compactionError).toBe('Unknown error during compaction');
@@ -539,7 +541,7 @@ describe('ContextManager', () => {
const { result } = renderContextManager(); const { result } = renderContextManager();
await act(async () => { await act(async () => {
await result.current.handleAutoCompaction(mockMessages, mockSetMessages, mockAppend); await result.current.handleAutoCompaction(mockMessages, mockSetMessages, mockAppend, "test-session-id");
}); });
// Should complete without error even if content is not text // Should complete without error even if content is not text
@@ -18,12 +18,14 @@ import { generateId } from 'ai';
export async function manageContextFromBackend({ export async function manageContextFromBackend({
messages, messages,
manageAction, manageAction,
sessionId,
}: { }: {
messages: FrontendMessage[]; messages: FrontendMessage[];
manageAction: 'truncation' | 'summarize'; manageAction: 'truncation' | 'summarize';
sessionId: string;
}): Promise<ContextManageResponse> { }): Promise<ContextManageResponse> {
try { try {
const contextManagementRequest = { manageAction, messages }; const contextManagementRequest = { manageAction, messages, sessionId };
// Cast to the API-expected type // Cast to the API-expected type
const result = await manageContext({ const result = await manageContext({