Skip to content

Commit

Permalink
getConversation: reduce usage
Browse files Browse the repository at this point in the history
  • Loading branch information
enricoros committed Dec 30, 2024
1 parent ec9243b commit 9969ccb
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 22 deletions.
27 changes: 16 additions & 11 deletions src/apps/chat/AppChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { createDMessageFromFragments, createDMessagePlaceholderIncomplete, DMess
import { createErrorContentFragment, createTextContentFragment, DMessageAttachmentFragment, DMessageContentFragment, duplicateDMessageFragmentsNoVoid } from '~/common/stores/chat/chat.fragments';
import { gcChatImageAssets } from '~/common/stores/chat/chat.gc';
import { getChatLLMId } from '~/common/stores/llms/store-llms';
import { getConversation, getConversationSystemPurposeId, isValidConversation, useConversation } from '~/common/stores/chat/store-chats';
import { getConversation, getConversationSystemPurposeId, useConversation } from '~/common/stores/chat/store-chats';
import { optimaActions, optimaOpenModels, optimaOpenPreferences, useSetOptimaAppMenu } from '~/common/layout/optima/useOptima';
import { themeBgAppChatComposer } from '~/common/app.theme';
import { useChatLLM } from '~/common/stores/llms/llms.hooks';
Expand Down Expand Up @@ -254,13 +254,20 @@ export function AppChat() {
}, [handleExecuteAndOutcome]);

const handleMessageRegenerateLastInFocusedPane = React.useCallback(async () => {
const focusedConversation = getConversation(focusedPaneConversationId);
if (focusedPaneConversationId && focusedConversation?.messages?.length) {
const lastMessage = focusedConversation.messages[focusedConversation.messages.length - 1];
if (lastMessage.role === 'assistant')
ConversationsManager.getHandler(focusedPaneConversationId).historyTruncateTo(lastMessage.id, -1);
await handleExecuteAndOutcome('generate-content', focusedConversation.id, 'chat-regenerate-last'); // truncate if assistant, then gen-text
}
// Ctrl + Shift + Z
if (!focusedPaneConversationId) return;
const cHandler = ConversationsManager.getHandler(focusedPaneConversationId);
if (!cHandler.isValid()) return;
const inputHistory = cHandler.historyViewHeadOrThrow('chat-regenerate-shortcut');
if (!inputHistory.length) return;

// remove the last message if assistant's
const lastMessage = inputHistory[inputHistory.length - 1];
if (lastMessage.role === 'assistant')
cHandler.historyTruncateTo(lastMessage.id, -1);

// generate: NOTE: this will replace the system message correctly
await handleExecuteAndOutcome('generate-content', focusedPaneConversationId, 'chat-regenerate-last'); // truncate if assistant, then gen-text
}, [focusedPaneConversationId, handleExecuteAndOutcome]);

const handleMessageBeamLastInFocusedPane = React.useCallback(async () => {
Expand All @@ -284,10 +291,8 @@ export function AppChat() {
const handleTextDiagram = React.useCallback((diagramConfig: DiagramConfig | null) => setDiagramConfig(diagramConfig), []);

const handleImagineFromText = React.useCallback(async (conversationId: DConversationId, subjectText: string) => {
const conversation = getConversation(conversationId);
if (!conversation)
return;
const cHandler = ConversationsManager.getHandler(conversationId);
if (!cHandler.isValid()) return;
const userImagineMessage = createDMessagePlaceholderIncomplete('user', `Thinking at the subject...`); // [chat] append user:imagine prompt
cHandler.messageAppend(userImagineMessage);
await imaginePromptFromTextOrThrow(subjectText, conversationId)
Expand Down
12 changes: 6 additions & 6 deletions src/apps/chat/components/composer/Composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ import { ShortcutKey, ShortcutObject, useGlobalShortcuts } from '~/common/compon
import { addSnackbar } from '~/common/components/snackbar/useSnackbarsStore';
import { animationEnterBelow } from '~/common/util/animUtils';
import { browserSpeechRecognitionCapability, PLACEHOLDER_INTERIM_TRANSCRIPT, SpeechResult, useSpeechRecognition } from '~/common/components/speechrecognition/useSpeechRecognition';
import { conversationTitle, DConversationId } from '~/common/stores/chat/chat.conversation';
import { DConversationId } from '~/common/stores/chat/chat.conversation';
import { copyToClipboard, supportsClipboardRead } from '~/common/util/clipboardUtils';
import { createTextContentFragment, DMessageAttachmentFragment, DMessageContentFragment, duplicateDMessageFragmentsNoVoid } from '~/common/stores/chat/chat.fragments';
import { estimateTextTokens, glueForMessageTokens, marshallWrapDocFragments } from '~/common/stores/chat/chat.tokens';
import { getConversation, isValidConversation, useChatStore } from '~/common/stores/chat/store-chats';
import { isValidConversation, useChatStore } from '~/common/stores/chat/store-chats';
import { getModelParameterValueOrThrow } from '~/common/stores/llms/llms.parameters';
import { launchAppCall, removeQueryParam, useRouterQuery } from '~/common/app.routes';
import { lineHeightTextareaMd } from '~/common/app.theme';
Expand Down Expand Up @@ -488,12 +488,12 @@ export function Composer(props: {

const onActileEmbedMessage = React.useCallback(async ({ conversationId, messageId }: StarredMessageItem) => {
// get the message
const conversation = getConversation(conversationId);
const messageToEmbed = conversation?.messages.find(m => m.id === messageId);
if (conversation && messageToEmbed) {
const cHandler = ConversationsManager.getHandler(conversationId);
const messageToEmbed = cHandler.historyFindMessageOrThrow(messageId);
if (messageToEmbed) {
const fragmentsCopy = duplicateDMessageFragmentsNoVoid(messageToEmbed.fragments); // [attach] deep copy a message's fragments to attach to ego
if (fragmentsCopy.length) {
const chatTitle = conversationTitle(conversation);
const chatTitle = cHandler.title() ?? '';
const messageText = messageFragmentsReduceText(fragmentsCopy);
const label = `${chatTitle} > ${messageText.slice(0, 10)}...`;
await attachAppendEgoFragments(fragmentsCopy, label, chatTitle, conversationId, messageId);
Expand Down
8 changes: 8 additions & 0 deletions src/common/chat-overlay/ConversationHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,14 @@ export class ConversationHandler {
return messages;
}

historyFindMessageOrThrow(messageId: DMessageId): Readonly<DMessage> | undefined {
return _chatStoreActions.historyView(this.conversationId)?.find(m => m.id === messageId);
}

title(): string | undefined {
return _chatStoreActions.title(this.conversationId);
}


// Beam

Expand Down
6 changes: 6 additions & 0 deletions src/common/stores/chat/store-chats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export interface ChatActions {
setAutoTitle: (cId: DConversationId, autoTitle: string) => void;
setUserTitle: (cId: DConversationId, userTitle: string) => void;
setUserSymbol: (cId: DConversationId, userSymbol: string | null) => void;
title: (cId: DConversationId) => string | undefined;

// utility function
_editConversation: (cId: DConversationId, update: Partial<DConversation> | ((conversation: DConversation) => Partial<DConversation>)) => void;
Expand Down Expand Up @@ -389,6 +390,11 @@ export const useChatStore = create<ConversationsStore>()(/*devtools(*/
...(!userTitle && { autoTitle: undefined }), // clear autotitle when clearing usertitle
}),

title: (conversationId: DConversationId): string | undefined => {
const existing = _get().conversations.find(_c => _c.id === conversationId);
return existing ? conversationTitle(existing) : undefined;
},

setUserSymbol: (conversationId: DConversationId, userSymbol: string | null) =>
_get()._editConversation(conversationId,
{
Expand Down
11 changes: 6 additions & 5 deletions src/modules/aifn/flatten/FlattenerModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { DConversationId } from '~/common/stores/chat/chat.conversation';
import { GoodModal } from '~/common/components/modals/GoodModal';
import { InlineTextarea } from '~/common/components/InlineTextarea';
import { createDMessageTextContent, DMessage, messageFragmentsReduceText } from '~/common/stores/chat/chat.message';
import { getConversation } from '~/common/stores/chat/store-chats';
import { useFormRadioLlmType } from '~/common/components/forms/useFormRadioLlmType';

import { FLATTEN_PROFILES, FlattenStyleType } from './flatten.data';
Expand Down Expand Up @@ -65,7 +64,7 @@ function FlatteningProgress(props: { llmLabel: string, partialText: string | nul
}


function encodeConversationAsUserMessage(userPrompt: string, messages: DMessage[]): string {
function encodeConversationAsUserMessage(userPrompt: string, messages: Readonly<DMessage[]>): string {
let encodedMessages = '';

for (const message of messages) {
Expand Down Expand Up @@ -103,9 +102,11 @@ export function FlattenerModal(props: {
const handlePerformFlattening = React.useCallback(async (flattenStyle: FlattenStyleType) => {

// validate config (or set error)
const conversation = getConversation(props.conversationId);
const messages = conversation?.messages;
if (!messages || !messages.length)
if (!props.conversationId)
return setErrorMessage('No conversation selected');
const cHandler = ConversationsManager.getHandler(props.conversationId);
const messages = !cHandler.isValid() ? [] : cHandler.historyViewHeadOrThrow('flattener-modal');
if (!messages.length)
return setErrorMessage('No messages in conversation');
if (!llm)
return setErrorMessage('No model selected');
Expand Down

0 comments on commit 9969ccb

Please sign in to comment.