[Agent Builder] Lift streaming provider + remove 'new' cache key#267324
Conversation
…versations mid stream
|
/ci |
|
/ci |
|
/ci |
|
/ci |
|
/ci |
| // Re-exported so consumers can keep importing `useSendMessage` from this file. The actual | ||
| // implementation lives in `./use_send_message` to avoid a circular import with | ||
| // `use_conversation.ts` (the per-conversation scoped hook reads from `useConversation()`, | ||
| // while `useConversation()` reads from `useSendMessageContext` here). | ||
| export { useSendMessage } from './use_send_message'; |
There was a problem hiding this comment.
Self review: this will be fixed/updated in a future PR. It will caused about 7 or so file changes in this diff with the renaming so I've decided to just re-export for now.
| agentReasoning: resumeAgentReasoning, | ||
| } = useResumeRoundMutation({ | ||
| connectorId: connectorSelection.selectedConnector, | ||
| const [activeStream, setActiveStream] = useState<ActiveStream | undefined>(undefined); |
There was a problem hiding this comment.
self-review: this is the shape that we want an active stream to be in for now. In a future PR, we will update this to be something like: Record<conversationId, ActiveStream | undefined> which is main change from the current code that will enable concurrent streams.
Today, we block any conversation from starting a stream if ANYTHING is streaming from any other conversation. With this change, each conversation will be able to check if THAT conversation is currently streaming - allowing each conversation to own it's own streaming lifecycle and not have to be concerned with any other conversation's streams.
💛 Build succeeded, but was flaky
Failed CI StepsTest Failures
Metrics [docs]Module Count
Async chunks
History
cc @chrisbmar |
closes https://github.com/elastic/search-team/issues/14293
closes https://github.com/elastic/search-team/issues/14319
Problems
'new' cache key. Frontend used 'new' as a placeholder cache key for unsaved conversations, renamed to the real id once the backend emitted one (~3s on average, which blocks other UI capabilities from being possible in that time). The cache rename + migration logic added ~300 lines of coordination and made per-conversation stream state hard to reason about.
Streaming provider scoped to the conversation tree.
<SendMessageProvider>was mounted inside the conversation route - the sidebar and other surfaces couldn't see streaming state.What this PR does
Removes 'new':
/conversations/<uuid>immediately, and writes the optimistic round under the real id from the outset.Lifts
<SendMessageProvider>to the app level:mount.tsx(routed) andembeddable_conversations_provider.tsx(per-instance for embeddable, since each has its own QueryClient).useSendMessageContext(); conversation tree uses the per-conversation scopeduseSendMessage().activeStream(which conversation is currently streaming) +byConversationId(per-conversation pending message, error, errorSteps).Each conversation now owns its streaming lifecycle:
mutationFnwithtry / catch / finally.streamActionsclosure-bound tovars.conversationId.messageControllerRef/isMutatingNewConversationRef/isRegeneratingRefrefs that bridged state across lifecycle callbacks.Per-conversation
useConversationgate:useConversationgated on a global "is anything streaming" flag — switching to conversation B while A streamed prevented B from loading.)Out of scope / follow-up
Other cleanup
connectorSelectionextracted fromSendMessageProvider- it's a global setting, not streaming state.retryOnMount: falseonuseConversation- prevents a refetch loop when a 404'd query has new observers mount (e.g., when a conversation is deleted and error state is shown).LocationErrorClearerremoved - errors now clear on explicit user actions: sidebar New Conversation button / conversation list / search modal selections etc. - this wasn't possible before because error state lived in the conversation tree and the sidebar knew nothing about it.usePendingMessageStatefolded intobyConversationId.Architecture docs
CONTRIBUTOR_GUIDE.md.Manual tests
(this uses a hardcoded error on the backend so retry doesn't work in the video but the FTR tests prove it, but you can see errors being cleared correctly when changing conversation)
error.handling.mov
HITL.mov
sidebar.mov
regenerate.round.response.mov
rename.delete.mov