diff --git a/src/apps/chat/components/ChatMessageList.tsx b/src/apps/chat/components/ChatMessageList.tsx
index 9cf24d27f..534ee7e49 100644
--- a/src/apps/chat/components/ChatMessageList.tsx
+++ b/src/apps/chat/components/ChatMessageList.tsx
@@ -374,7 +374,6 @@ export function ChatMessageList(props: {
sx={{
mt: 'auto',
overflowY: 'auto',
- minHeight: 64,
}}
/>
)}
diff --git a/src/apps/chat/components/Ephemerals.tsx b/src/apps/chat/components/Ephemerals.tsx
index 3bfb26f6a..aab8460f4 100644
--- a/src/apps/chat/components/Ephemerals.tsx
+++ b/src/apps/chat/components/Ephemerals.tsx
@@ -3,7 +3,8 @@ import * as React from 'react';
import type { SxProps } from '@mui/joy/styles/types';
import { Box, Grid, IconButton, Sheet, styled, Typography } from '@mui/joy';
import CloseRoundedIcon from '@mui/icons-material/CloseRounded';
-import PushPinIcon from '@mui/icons-material/PushPin';
+import MaximizeIcon from '@mui/icons-material/Maximize';
+import MinimizeIcon from '@mui/icons-material/Minimize';
import VerticalSplitIcon from '@mui/icons-material/VerticalSplit';
import VerticalSplitOutlinedIcon from '@mui/icons-material/VerticalSplitOutlined';
@@ -111,107 +112,112 @@ function EphemeralItem(props: {
const { ephemeral, conversationHandler } = props;
+ // Event handlers
const handleDelete = React.useCallback(() => {
conversationHandler.overlayActions.ephemeralsDelete(ephemeral.id);
}, [conversationHandler, ephemeral.id]);
- const handleTogglePinned = React.useCallback(() => {
- conversationHandler.overlayActions.ephemeralsTogglePinned(ephemeral.id);
+ const handleToggleMinimized = React.useCallback(() => {
+ conversationHandler.overlayActions.ephemeralsToggleMinimized(ephemeral.id);
}, [conversationHandler, ephemeral.id]);
const handleToggleShowState = React.useCallback(() => {
- conversationHandler.overlayActions.ephemeralsToggleShowState(ephemeral.id);
+ conversationHandler.overlayActions.ephemeralsToggleShowStatePane(ephemeral.id);
}, [conversationHandler, ephemeral.id]);
- const showStatePane = ephemeral.showState && !!ephemeral.state;
- return
-
- {/* Title */}
- {ephemeral.title && (
-
- {ephemeral.title} Internal Monologue
-
- )}
-
- {/* Vertical | split */}
-
-
- {/* Left pane (log) */}
-
- {/* New renderer, with */}
-
-
-
-
-
- {/* Right pane (state) */}
- {showStatePane && (
-
-
-
- )}
-
-
-
-
- {/* Buttons */}
-
- {/* Pin */}
- *': { transition: 'transform 0.2s' },
- }}
- >
-
-
+ {/* Top Line - Title and Buttons */}
+
- {/* Show State */}
-
- {ephemeral.showState ? : }
-
+
+ {ephemeral.title} Internal Monologue
+
- {/* Close */}
-
-
-
+ {/* Show State */}
+ {!ephemeral.minimized && (
+
+ {ephemeral.showStatePane ? : }
+
+ )}
+
+ {/* Minimize/Expand Button */}
+
+ {ephemeral.minimized ? : }
+
+
+ {/* Close */}
+
+
+
+
+
+
+ {/* Content */}
+ {!ephemeral.minimized &&
+
+ {/* Content Grid */}
+
+
+ {/* Left pane (log) */}
+
+ {/* New renderer, with */}
+
+
+
+
+
+ {/* Right pane (state) */}
+ {showStatePane && (
+
+
+
+ )}
+
+
+ }
-
- ;
+ );
}
diff --git a/src/common/chat-overlay/ConversationHandler.ts b/src/common/chat-overlay/ConversationHandler.ts
index 2a39275fc..f4f18e765 100644
--- a/src/common/chat-overlay/ConversationHandler.ts
+++ b/src/common/chat-overlay/ConversationHandler.ts
@@ -14,14 +14,10 @@ import { getChatLLMId } from '~/common/stores/llms/store-llms';
import { getChatAutoAI } from '../../apps/chat/store-app-chat';
-import { createDEphemeral } from './store-perchat_ephemerals_slice';
+import { createDEphemeral, EPHEMERALS_DEFAULT_TIMEOUT } from './store-perchat_ephemerals_slice';
import { createPerChatVanillaStore } from './store-perchat_vanilla';
-// configuration
-const EPHEMERAL_DELETION_DELAY = 5 * 1000;
-
-
/**
* ConversationHandler is a class to overlay state onto a conversation.
* It is a singleton per conversationId.
@@ -250,16 +246,15 @@ export class ConversationHandler {
// Ephemerals
createEphemeralHandler(title: string, initialText: string) {
- const { ephemeralsAppend, ephemeralsUpdate, ephemeralsDelete, ephemeralsIsPinned } = this.overlayActions;
+ const { ephemeralsAppend, ephemeralsUpdate, ephemeralsDelete, getEphemeral } = this.overlayActions;
// create and append
const ephemeral = createDEphemeral(title, initialText);
const eId = ephemeral.id;
ephemeralsAppend(ephemeral);
- // delete if not pinned
- const deleteIfNotPinned = () => {
- if (!ephemeralsIsPinned(eId))
+ const deleteIfMinimized = () => {
+ if (getEphemeral(eId)?.minimized)
ephemeralsDelete(eId);
};
@@ -269,7 +264,7 @@ export class ConversationHandler {
updateState: (state: object) => ephemeralsUpdate(eId, { state }),
markAsDone: () => {
ephemeralsUpdate(eId, { done: true });
- setTimeout(deleteIfNotPinned, EPHEMERAL_DELETION_DELAY);
+ setTimeout(deleteIfMinimized, EPHEMERALS_DEFAULT_TIMEOUT);
},
};
}
diff --git a/src/common/chat-overlay/store-perchat_ephemerals_slice.ts b/src/common/chat-overlay/store-perchat_ephemerals_slice.ts
index 9b4c55862..2aea4f48c 100644
--- a/src/common/chat-overlay/store-perchat_ephemerals_slice.ts
+++ b/src/common/chat-overlay/store-perchat_ephemerals_slice.ts
@@ -3,6 +3,11 @@ import type { StateCreator } from 'zustand/vanilla';
import { agiUuid } from '~/common/util/idUtils';
+// configuration
+export const EPHEMERALS_DEFAULT_TIMEOUT = 6000;
+const EPHEMERALS_DEFAULT_MINIMIZED = true;
+
+
/**
* DEphemeral: For ReAct sidebars, displayed under the chat
*/
@@ -11,9 +16,9 @@ export interface DEphemeral {
title: string;
text: string;
state: object;
- done: boolean;
- pinned: boolean;
- showState: boolean;
+ done: boolean; // is complete, shall close after timeout
+ minimized: boolean; // collapsed to a single line
+ showStatePane: boolean; // show the state object
}
type DEphemeralId = string;
@@ -25,16 +30,16 @@ export function createDEphemeral(title: string, initialText: string): DEphemeral
text: initialText,
state: {},
done: false,
- pinned: lastEphemeralPinned,
- showState: lastEphemeralShowState,
+ minimized: lastMinimized,
+ showStatePane: lastShowStatePane,
};
}
/// Ephemerals Overlay Store ///
-let lastEphemeralPinned = false;
-let lastEphemeralShowState = false;
+let lastMinimized = EPHEMERALS_DEFAULT_MINIMIZED;
+let lastShowStatePane = false;
interface EphemeralsOverlayState {
@@ -48,11 +53,10 @@ export interface EphemeralsOverlayStore extends EphemeralsOverlayState {
ephemeralsDelete: (ephemeralId: DEphemeralId) => void;
ephemeralsUpdate: (ephemeralId: DEphemeralId, update: Partial) => void;
- ephemeralsIsPinned: (ephemeralId: DEphemeralId) => boolean;
- ephemeralsTogglePinned: (ephemeralId: DEphemeralId) => void;
+ ephemeralsToggleMinimized: (ephemeralId: DEphemeralId) => void;
+ ephemeralsToggleShowStatePane: (ephemeralId: DEphemeralId) => void;
- ephemeralsIsShowState: (ephemeralId: DEphemeralId) => boolean;
- ephemeralsToggleShowState: (ephemeralId: DEphemeralId) => void;
+ getEphemeral: (ephemeralId: DEphemeralId) => Readonly | undefined;
}
@@ -75,10 +79,10 @@ export const createEphemeralsOverlayStoreSlice: StateCreator
_set((state) => {
- if (update.pinned !== undefined)
- lastEphemeralPinned = update.pinned;
- if (update.showState !== undefined)
- lastEphemeralShowState = update.showState;
+ if (update.minimized !== undefined)
+ lastMinimized = update.minimized;
+ if (update.showStatePane !== undefined)
+ lastShowStatePane = update.showStatePane;
return {
ephemerals: state.ephemerals.map((e) =>
e.id === ephemeralId
@@ -88,28 +92,21 @@ export const createEphemeralsOverlayStoreSlice: StateCreator
- _get().ephemerals.find((e) => e.id === ephemeralId)?.pinned || false,
-
- ephemeralsTogglePinned: (ephemeralId) => {
- const { ephemerals, ephemeralsDelete, ephemeralsUpdate } = _get();
- const ephemeral = ephemerals.find((e) => e.id === ephemeralId);
- if (ephemeral) {
- if (ephemeral.pinned && ephemeral.done)
- ephemeralsDelete(ephemeralId);
- else
- ephemeralsUpdate(ephemeralId, { pinned: !ephemeral.pinned });
- }
- },
-
- ephemeralsIsShowState: (ephemeralId) =>
- _get().ephemerals.find((e) => e.id === ephemeralId)?.showState || false,
-
- ephemeralsToggleShowState: (ephemeralId) => {
+ ephemeralsToggleMinimized: (ephemeralId) => {
const { ephemerals, ephemeralsUpdate } = _get();
const ephemeral = ephemerals.find((e) => e.id === ephemeralId);
if (ephemeral)
- ephemeralsUpdate(ephemeralId, { showState: !ephemeral.showState });
+ ephemeralsUpdate(ephemeralId, { minimized: !ephemeral.minimized });
},
+ ephemeralsToggleShowStatePane: (ephemeralId) => {
+ const { ephemerals, ephemeralsUpdate } = _get();
+ const ephemeral = ephemerals.find((e) => e.id === ephemeralId);
+ if (ephemeral)
+ ephemeralsUpdate(ephemeralId, { showStatePane: !ephemeral.showStatePane });
+ },
+
+ getEphemeral: (ephemeralId) =>
+ _get().ephemerals.find((e) => e.id === ephemeralId),
+
});