Skip to content

Commit

Permalink
fix(Assistant): Rework realtime usage for instant messages
Browse files Browse the repository at this point in the history
it's necessary to use a dependency on the useRealtime hook to avoid subscribing/unsubscribing at each render and therefore losing information
  • Loading branch information
JF-Cozy committed Nov 4, 2024
1 parent f3d9d6d commit 9abcd23
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 42 deletions.
86 changes: 47 additions & 39 deletions src/assistant/AssistantProvider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,49 +26,57 @@ const AssistantProvider = ({ children }) => {
messagesId: []
})

useRealtime(client, {
[CHAT_CONVERSATIONS_DOCTYPE]: {
created: res => {
pushMessagesIdInState(res, setAssistantState)
},
updated: res => {
pushMessagesIdInState(res, setAssistantState)
}
}
})

useRealtime(client, {
[CHAT_EVENTS_DOCTYPE]: {
created: res => {
// to exclude realtime messages if not relevant to the actual conversation
if (!isMessageForThisConversation(res, assistantState.messagesId)) {
return
useRealtime(
client,
{
[CHAT_CONVERSATIONS_DOCTYPE]: {
created: res => {
pushMessagesIdInState(res, setAssistantState)
},
updated: res => {
pushMessagesIdInState(res, setAssistantState)
}
}
},
[]
)

if (res.object === 'done') {
if (assistantState.status !== 'idle') {
// to be sure the last response is inside io.cozy.ai.chat.conversations
setTimeout(() => {
setAssistantState(v => ({
...v,
status: 'idle'
}))
}, 250)
}
}

if (res.object === 'delta') {
const message = set(assistantState.message, res.position, res.content)

setAssistantState(v => ({
...v,
message,
status: 'writing'
}))
useRealtime(
client,
{
[CHAT_EVENTS_DOCTYPE]: {
created: res => {
setAssistantState(prevState => {
// to exclude realtime messages if not relevant to the actual conversation
if (!isMessageForThisConversation(res, prevState.messagesId)) {
return prevState
}

if (res.object === 'done') {
if (prevState.status !== 'idle') {
return {
...prevState,
status: 'idle'
}
}
}

if (res.object === 'delta') {
const message = set(prevState.message, res.position, res.content)
return {
...prevState,
message,
status: 'writing'
}
}

return prevState
})
}
}
}
})
},
[]
)

const clearAssistant = useCallback(
() =>
Expand Down
10 changes: 7 additions & 3 deletions src/assistant/Conversations/ChatConversation.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ const ChatConversation = ({ conversation, myself }) => {
const { assistantState } = useAssistant()
const listRef = useRef()

const showLastConv = assistantState.status !== 'idle'
// test on role === user to be sure the last response is inside io.cozy.ai.chat.conversations
const showRealtimeMessage =
assistantState.status !== 'idle' ||
conversation?.messages?.[conversation?.messages?.length - 1]?.role ===
'user'

useEffect(() => {
// force scroll down if new message of change in AI instant response
Expand Down Expand Up @@ -50,7 +54,7 @@ const ChatConversation = ({ conversation, myself }) => {
)
}

if (showLastConv) {
if (showRealtimeMessage) {
return null
}

Expand All @@ -65,7 +69,7 @@ const ChatConversation = ({ conversation, myself }) => {
)
})}

{showLastConv && (
{showRealtimeMessage && (
<ChatRealtimeAnswer
isLoading={assistantState.status === 'pending'}
label={getInstantMessage(assistantState)}
Expand Down

0 comments on commit 9abcd23

Please sign in to comment.