diff --git a/src/apps/call/Telephone.tsx b/src/apps/call/Telephone.tsx index 34018a45a..1833591be 100644 --- a/src/apps/call/Telephone.tsx +++ b/src/apps/call/Telephone.tsx @@ -193,16 +193,19 @@ export function Telephone(props: { // do not respond case 'Stop.': return; + // command: close the call case 'Goodbye.': setStage('ended'); setTimeout(launchAppChat, 2000); return; + // command: regenerate answer case 'Retry.': case 'Try again.': setCallMessages(messages => messages.slice(0, messages.length - 2)); return; + // command: restart chat case 'Restart.': setCallMessages([]); diff --git a/src/apps/chat/components/ChatBarAltTitle.tsx b/src/apps/chat/components/ChatBarAltTitle.tsx index 08bc0bd0c..f28e1f299 100644 --- a/src/apps/chat/components/ChatBarAltTitle.tsx +++ b/src/apps/chat/components/ChatBarAltTitle.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import { Box, Typography } from '@mui/joy'; import AutoFixHighIcon from '@mui/icons-material/AutoFixHigh'; -import { conversationAutoTitle } from '~/modules/aifn/autotitle/autoTitle'; +import { autoConversationTitle } from '~/modules/aifn/autotitle/autoTitle'; import { DConversationId } from '~/common/stores/chat/chat.conversation'; import { capitalizeFirstLetter } from '~/common/util/textUtils'; @@ -29,7 +29,7 @@ export function ChatBarAltTitle(props: { const handleTitleEditAuto = React.useCallback(async () => { if (!conversationId) return; setIsEditingTitle(true); - await conversationAutoTitle(conversationId, true); + await autoConversationTitle(conversationId, true); setIsEditingTitle(false); }, [conversationId]); diff --git a/src/apps/chat/components/ChatDrawerItem.tsx b/src/apps/chat/components/ChatDrawerItem.tsx index c4be86b58..d6bbb7e14 100644 --- a/src/apps/chat/components/ChatDrawerItem.tsx +++ b/src/apps/chat/components/ChatDrawerItem.tsx @@ -13,7 +13,7 @@ import ForkRightIcon from '@mui/icons-material/ForkRight'; import { SystemPurposeId, SystemPurposes } from '../../../data'; -import { conversationAutoTitle } from '~/modules/aifn/autotitle/autoTitle'; +import { autoConversationTitle } from '~/modules/aifn/autotitle/autoTitle'; import type { DConversationId } from '~/common/stores/chat/chat.conversation'; import type { DFolder } from '~/common/state/store-folders'; @@ -149,7 +149,7 @@ function ChatDrawerItem(props: { const handleTitleEditAuto = React.useCallback(async () => { setIsAutoEditingTitle(true); - await conversationAutoTitle(conversationId, true); + await autoConversationTitle(conversationId, true); setIsAutoEditingTitle(false); }, [conversationId]); diff --git a/src/apps/chat/components/useChatDrawerRenderItems.tsx b/src/apps/chat/components/useChatDrawerRenderItems.tsx index d0eca57b9..8019579da 100644 --- a/src/apps/chat/components/useChatDrawerRenderItems.tsx +++ b/src/apps/chat/components/useChatDrawerRenderItems.tsx @@ -1,4 +1,5 @@ import { shallow } from 'zustand/shallow'; +import { useStoreWithEqualityFn } from 'zustand/traditional'; import type { DFolder } from '~/common/state/store-folders'; import { DMessageUserFlag, messageFragmentsReduceText, messageHasUserFlag, messageUserFlagToEmoji } from '~/common/stores/chat/chat.message'; @@ -101,7 +102,7 @@ export function useChatDrawerRenderItems( filteredChatsBarBasis: number, filteredChatsIncludeActive: boolean, } { - return useChatStore(({ conversations }) => { + return useStoreWithEqualityFn(useChatStore, ({ conversations }) => { // filter 1: select all conversations or just the ones in the active folder const selectedConversations = !activeFolder ? conversations : conversations.filter(_c => activeFolder.conversationIds.includes(_c.id)); diff --git a/src/apps/chat/editors/chat-stream.ts b/src/apps/chat/editors/chat-stream.ts index 46f9cb547..e7651aa8a 100644 --- a/src/apps/chat/editors/chat-stream.ts +++ b/src/apps/chat/editors/chat-stream.ts @@ -1,7 +1,7 @@ import type { DLLMId } from '~/modules/llms/store-llms'; import type { StreamingClientUpdate } from '~/modules/llms/vendors/unifiedStreamingClient'; import { autoSuggestions } from '~/modules/aifn/autosuggestions/autoSuggestions'; -import { conversationAutoTitle } from '~/modules/aifn/autotitle/autoTitle'; +import { autoConversationTitle } from '~/modules/aifn/autotitle/autoTitle'; import { llmStreamingChatGenerate, VChatContextRef, VChatMessageIn, VChatStreamContextName } from '~/modules/llms/llm.client'; import { speakText } from '~/modules/elevenlabs/elevenlabs.client'; @@ -51,7 +51,7 @@ export async function runAssistantUpdatingState(conversationId: string, history: if (autoTitleChat) { // fire/forget, this will only set the title if it's not already set - void conversationAutoTitle(conversationId, false); + void autoConversationTitle(conversationId, false); } if (autoSuggestDiagrams || autoSuggestQuestions) diff --git a/src/common/stores/chat/chat.message.ts b/src/common/stores/chat/chat.message.ts index 334a198a3..9305e4327 100644 --- a/src/common/stores/chat/chat.message.ts +++ b/src/common/stores/chat/chat.message.ts @@ -49,21 +49,24 @@ export type DMessageFragment = // | DMessageMetadataV1Fragment ; +// expected a list of one or more per message, of similar or different types export type DMessageContentFragment = { ft: 'content', part: DMessageTextPart | DMessageImagePart | DMessageToolCallPart | DMessageToolResponsePart; } +// displayed at the bottom of the message, zero or more export type DMessageAttachmentFragment = { ft: 'attachment', title: string; part: DMessageTextPart | DMessageImagePart; } -// Up to 1 per message, containing the Rays and Merges that would be used to restore the Beam state -// export type DMessageBeamFragment = { +// up to 1 per message, containing the Rays and Merges that would be used to restore the Beam state - could be volatile (omitted at save) +// could not be the data store itself, but only used for save/reload +// export type DMessageBeasmFragment = { // ft: 'beam', -// beam: { ... } +// beam: { ... serializedState ... } // } diff --git a/src/modules/aifn/autotitle/autoTitle.ts b/src/modules/aifn/autotitle/autoTitle.ts index f65453530..f5e49d55a 100644 --- a/src/modules/aifn/autotitle/autoTitle.ts +++ b/src/modules/aifn/autotitle/autoTitle.ts @@ -9,7 +9,7 @@ import { useChatStore } from '~/common/stores/chat/store-chats'; * Creates the AI titles for conversations, by taking the last 5 first-lines and asking AI what's that about * @returns true if the title was actually replaced (for instance, it may not be needed) */ -export async function conversationAutoTitle(conversationId: string, forceReplace: boolean): Promise { +export async function autoConversationTitle(conversationId: string, forceReplace: boolean): Promise { // use valid fast model const fastLLMId = getFastLLMId(); diff --git a/src/modules/beam/gather/Fusion.tsx b/src/modules/beam/gather/Fusion.tsx index 2b7c2c34e..2bf005ef5 100644 --- a/src/modules/beam/gather/Fusion.tsx +++ b/src/modules/beam/gather/Fusion.tsx @@ -66,7 +66,7 @@ export function Fusion(props: { // handlers - const handleFusionCopy = React.useCallback(() => { + const handleFusionCopyToClipboard = React.useCallback(() => { const { fusions } = props.beamStore.getState(); const fusion = fusions.find(fusion => fusion.fusionId === props.fusionId); if (fusion?.outputDMessage?.fragments.length) @@ -161,7 +161,7 @@ export function Fusion(props: { {/* Copy */} diff --git a/src/modules/beam/scatter/BeamRay.tsx b/src/modules/beam/scatter/BeamRay.tsx index 07b7295bc..b69a825c9 100644 --- a/src/modules/beam/scatter/BeamRay.tsx +++ b/src/modules/beam/scatter/BeamRay.tsx @@ -146,7 +146,7 @@ export function BeamRay(props: { // handlers - const handleRayCopy = React.useCallback(() => { + const handleRayCopyToClipboard = React.useCallback(() => { const { rays } = props.beamStore.getState(); const ray = rays.find(ray => ray.rayId === props.rayId); if (ray?.message.fragments.length) @@ -232,7 +232,7 @@ export function BeamRay(props: {