@@ -61,12 +61,15 @@ export const useChatSend = ({
6161 const { setLastConversation } = useAssistantLastConversation ( { spaceId } ) ;
6262 const [ userPrompt , setUserPrompt ] = useState < string | null > ( null ) ;
6363
64- const { isLoading , sendMessage, abortStream } = useSendMessage ( ) ;
64+ const { sendMessage, abortStream } = useSendMessage ( ) ;
6565 const { clearConversation, createConversation, getConversation, removeLastMessage } =
6666 useConversation ( ) ;
6767 const { data : kbStatus } = useKnowledgeBaseStatus ( { http, enabled : isAssistantEnabled } ) ;
6868 const isSetupComplete = kbStatus ?. elser_exists && kbStatus ?. security_labs_exists ;
6969
70+ // Local loading state that persists until the entire message flow is complete
71+ const [ isLoadingChatSend , setIsLoadingChatSend ] = useState ( false ) ;
72+
7073 // Handles sending latest user prompt to API
7174 const handleSendMessage = useCallback (
7275 async ( promptText : string ) => {
@@ -99,61 +102,80 @@ export const useChatSend = ({
99102 selectedPromptContexts,
100103 } ) ;
101104
102- const baseReplacements : Replacements = userMessage . replacements ?? convo . replacements ;
103-
104- const selectedPromptContextsReplacements = Object . values (
105- selectedPromptContexts
106- ) . reduce < Replacements > ( ( acc , context ) => ( { ...acc , ...context . replacements } ) , { } ) ;
107-
108- const replacements : Replacements = {
109- ...baseReplacements ,
110- ...selectedPromptContextsReplacements ,
111- } ;
112- const updatedMessages = [ ...convo . messages , userMessage ] . map ( ( m ) => ( {
113- ...m ,
114- content : m . content ?? '' ,
115- } ) ) ;
116- setCurrentConversation ( {
117- ...convo ,
118- replacements,
119- messages : updatedMessages ,
120- } ) ;
105+ const baseReplacements : Replacements = userMessage . replacements ?? convo . replacements ;
121106
122- // Reset prompt context selection and preview before sending:
123- setSelectedPromptContexts ( { } ) ;
107+ const selectedPromptContextsReplacements = Object . values (
108+ selectedPromptContexts
109+ ) . reduce < Replacements > ( ( acc , context ) => ( { ...acc , ...context . replacements } ) , { } ) ;
124110
125- const rawResponse = await sendMessage ( {
126- apiConfig,
127- http,
128- message : userMessage . content ?? '' ,
129- conversationId : convo . id ,
130- replacements,
131- } ) ;
111+ const replacements : Replacements = {
112+ ...baseReplacements ,
113+ ...selectedPromptContextsReplacements ,
114+ } ;
115+ const updatedMessages = [ ...convo . messages , userMessage ] . map ( ( m ) => ( {
116+ ...m ,
117+ content : m . content ?? '' ,
118+ } ) ) ;
119+ setCurrentConversation ( {
120+ ...convo ,
121+ replacements,
122+ messages : updatedMessages ,
123+ } ) ;
132124
133- assistantTelemetry ?. reportAssistantMessageSent ( {
134- role : userMessage . role ,
135- actionTypeId : apiConfig . actionTypeId ,
136- model : apiConfig . model ,
137- provider : apiConfig . provider ,
138- isEnabledKnowledgeBase : isSetupComplete ?? false ,
139- } ) ;
125+ // Reset prompt context selection and preview before sending:
126+ setSelectedPromptContexts ( { } ) ;
127+
128+ const rawResponse = await sendMessage ( {
129+ apiConfig,
130+ http,
131+ message : userMessage . content ?? '' ,
132+ conversationId : convo . id ,
133+ replacements,
134+ } ) ;
135+
136+ assistantTelemetry ?. reportAssistantMessageSent ( {
137+ role : userMessage . role ,
138+ actionTypeId : apiConfig . actionTypeId ,
139+ model : apiConfig . model ,
140+ provider : apiConfig . provider ,
141+ isEnabledKnowledgeBase : isSetupComplete ?? false ,
142+ } ) ;
140143
141- const responseMessage : ClientMessage = getMessageFromRawResponse ( rawResponse ) ;
142- if ( convo . title === '' ) {
143- convo . title = ( await getConversation ( convo . id ) ) ?. title ?? '' ;
144+ const responseMessage : ClientMessage = getMessageFromRawResponse ( rawResponse ) ;
145+ if ( convo . title === '' ) {
146+ // Retry getConversation up to 5 times if title is empty
147+ let retryCount = 0 ;
148+ const maxRetries = 5 ;
149+ while ( retryCount < maxRetries ) {
150+ const conversation = await getConversation ( convo . id ) ;
151+ convo . title = conversation ?. title ?? '' ;
152+
153+ if ( convo . title !== '' ) {
154+ break ; // Title found, exit retry loop
155+ }
156+
157+ retryCount ++ ;
158+ if ( retryCount < maxRetries ) {
159+ // Wait 1 second before next retry
160+ await new Promise ( ( resolve ) => setTimeout ( resolve , 1000 ) ) ;
161+ }
162+ }
163+ }
164+ setCurrentConversation ( {
165+ ...convo ,
166+ replacements,
167+ messages : [ ...updatedMessages , responseMessage ] ,
168+ } ) ;
169+ assistantTelemetry ?. reportAssistantMessageSent ( {
170+ role : responseMessage . role ,
171+ actionTypeId : apiConfig . actionTypeId ,
172+ model : apiConfig . model ,
173+ provider : apiConfig . provider ,
174+ isEnabledKnowledgeBase : isSetupComplete ?? false ,
175+ } ) ;
176+ } finally {
177+ setIsLoadingChatSend ( false ) ;
144178 }
145- setCurrentConversation ( {
146- ...convo ,
147- replacements,
148- messages : [ ...updatedMessages , responseMessage ] ,
149- } ) ;
150- assistantTelemetry ?. reportAssistantMessageSent ( {
151- role : responseMessage . role ,
152- actionTypeId : apiConfig . actionTypeId ,
153- model : apiConfig . model ,
154- provider : apiConfig . provider ,
155- isEnabledKnowledgeBase : isSetupComplete ?? false ,
156- } ) ;
157179 } ,
158180 [
159181 assistantTelemetry ,
@@ -241,7 +263,7 @@ export const useChatSend = ({
241263 handleChatSend,
242264 abortStream,
243265 handleRegenerateResponse,
244- isLoading,
266+ isLoading : isLoadingChatSend ,
245267 userPrompt,
246268 setUserPrompt,
247269 } ;
0 commit comments