@@ -154,7 +154,7 @@ const ChatBox = ({
154154 const questionGuideController = useRef ( new AbortController ( ) ) ;
155155 const pluginController = useRef ( new AbortController ( ) ) ;
156156 const resumeController = useRef < AbortController > ( ) ;
157- const resumedChatIdRef = useRef < string > ( ) ;
157+ const resumedChatTargetRef = useRef < string > ( ) ;
158158
159159 const [ isLoading , setIsLoading ] = useState ( false ) ;
160160 const [ feedbackId , setFeedbackId ] = useState < string > ( ) ;
@@ -180,6 +180,8 @@ const ChatBox = ({
180180
181181 const appId = useContextSelector ( WorkflowRuntimeContext , ( v ) => v . appId ) ;
182182 const chatId = useContextSelector ( WorkflowRuntimeContext , ( v ) => v . chatId ) ;
183+ const activeAppIdRef = useRef < string | undefined > ( appId ) ;
184+ activeAppIdRef . current = appId ;
183185 const activeChatIdRef = useRef < string | undefined > ( chatId ) ;
184186 activeChatIdRef . current = chatId ;
185187 const outLinkAuthData = useContextSelector ( WorkflowRuntimeContext , ( v ) => v . outLinkAuthData ) ;
@@ -198,18 +200,21 @@ const ChatBox = ({
198200 const syncSidebarChatGenerateStatus = useMemoizedFn (
199201 (
200202 status : ChatGenerateStatusEnum ,
201- options ?: { hasBeenRead ?: boolean ; targetChatId ?: string }
203+ options ?: { hasBeenRead ?: boolean ; targetAppId ?: string ; targetChatId ?: string }
202204 ) => {
205+ const targetAppId = options ?. targetAppId ?? appId ;
206+ if ( targetAppId !== appId ) return ;
207+
203208 const targetChatId = options ?. targetChatId ?? chatId ;
204209 if ( ! targetChatId ) return ;
205210 setHistories ( ( prev ) => {
206- const idx = prev . findIndex ( ( h ) => h . chatId === targetChatId ) ;
211+ const idx = prev . findIndex ( ( h ) => h . chatId === targetChatId && h . appId === targetAppId ) ;
207212 if ( idx === - 1 ) {
208213 queueMicrotask ( loadHistories ) ;
209214 return [
210215 {
211216 chatId : targetChatId ,
212- appId,
217+ appId : targetAppId ,
213218 title : chatBoxData . title || t ( 'common:core.chat.New Chat' ) ,
214219 customTitle : '' ,
215220 top : false ,
@@ -221,7 +226,7 @@ const ChatBox = ({
221226 ] ;
222227 }
223228 return prev . map ( ( h ) =>
224- h . chatId === targetChatId
229+ h . chatId === targetChatId && h . appId === targetAppId
225230 ? {
226231 ...h ,
227232 chatGenerateStatus : status ,
@@ -662,16 +667,26 @@ const ChatBox = ({
662667 } ) ;
663668 } ) ;
664669
670+ const isActiveResumeTarget = useMemoizedFn (
671+ ( { appId, chatId } : { appId : string ; chatId : string } ) =>
672+ activeAppIdRef . current === appId && activeChatIdRef . current === chatId
673+ ) ;
674+
665675 const getResumeUnavailablePlaceholderText = useMemoizedFn ( ( ) =>
666676 t ( 'chat:resume_placeholder_generating' )
667677 ) ;
668678
669679 const upsertResumeAiPlaceholder = useMemoizedFn (
670- ( responseChatId : string , text = '' , status : `${ChatStatusEnum } ` = ChatStatusEnum . loading ) => {
680+ (
681+ responseChatId : string ,
682+ text = '' ,
683+ status : `${ChatStatusEnum } ` = ChatStatusEnum . loading ,
684+ options ?: { resetExistingValue ?: boolean }
685+ ) => {
671686 setChatRecords ( ( state ) => {
672687 const lastItem = state [ state . length - 1 ] ;
673688 if ( lastItem ?. dataId === responseChatId && lastItem . obj === ChatRoleEnum . AI ) {
674- if ( ! text ) {
689+ if ( ! text && ! options ?. resetExistingValue ) {
675690 return state ;
676691 }
677692
@@ -687,6 +702,7 @@ const ChatBox = ({
687702 }
688703 }
689704 ] ,
705+ responseData : options ?. resetExistingValue ? [ ] : item . responseData ,
690706 status,
691707 ...( status === ChatStatusEnum . finish ? { time : new Date ( ) } : { } )
692708 }
@@ -833,7 +849,7 @@ const ChatBox = ({
833849 }
834850 ] ;
835851
836- resumedChatIdRef . current = chatId ;
852+ resumedChatTargetRef . current = ` ${ appId } : ${ chatId } ` ;
837853
838854 setChatBoxData ( ( state ) =>
839855 state . chatId === chatId
@@ -1252,8 +1268,12 @@ const ChatBox = ({
12521268 useEffect ( ( ) => {
12531269 setQuestionGuide ( [ ] ) ;
12541270 setValue ( 'chatStarted' , false ) ;
1255- resumedChatIdRef . current = undefined ;
1256- abortRequest ( 'leave' ) ;
1271+ resumedChatTargetRef . current = undefined ;
1272+ // abortRequest('leave');
1273+
1274+ return ( ) => {
1275+ abortRequest ( 'leave' ) ;
1276+ } ;
12571277 } , [ chatId , appId , abortRequest , setValue ] ) ;
12581278
12591279 useEffect ( ( ) => {
@@ -1264,20 +1284,24 @@ const ChatBox = ({
12641284 ! appId ||
12651285 ! chatId ||
12661286 isChatting ||
1287+ chatBoxData . appId !== appId ||
1288+ chatBoxData . chatId !== chatId ||
12671289 chatBoxData . chatGenerateStatus !== ChatGenerateStatusEnum . generating ||
1268- resumedChatIdRef . current === chatId
1290+ resumedChatTargetRef . current === ` ${ appId } : ${ chatId } `
12691291 ) {
12701292 return ;
12711293 }
12721294
1273- resumedChatIdRef . current = chatId ;
1295+ resumedChatTargetRef . current = ` ${ appId } : ${ chatId } ` ;
12741296
1297+ const resumeForAppId = appId ;
12751298 const resumeForChatId = chatId ;
12761299 const responseChatId = resumeTargetAiDataId ?? getNanoid ( 24 ) ;
12771300 const controller = new AbortController ( ) ;
12781301 resumeController . current = controller ;
12791302 scrollToBottom ( 'auto' ) ;
12801303 let resumeFinalStatus = ChatGenerateStatusEnum . done ;
1304+ let hasPreparedResumeAiRecord = false ;
12811305
12821306 ( async ( ) => {
12831307 try {
@@ -1287,7 +1311,7 @@ const ChatBox = ({
12871311 outLinkAuthData,
12881312 controller,
12891313 onResumeUnavailable : ( ) => {
1290- if ( resumeForChatId !== activeChatIdRef . current ) return ;
1314+ if ( ! isActiveResumeTarget ( { appId : resumeForAppId , chatId : resumeForChatId } ) ) return ;
12911315 resumeFinalStatus = ChatGenerateStatusEnum . generating ;
12921316 upsertResumeAiPlaceholder (
12931317 responseChatId ,
@@ -1296,15 +1320,18 @@ const ChatBox = ({
12961320 ) ;
12971321 } ,
12981322 onmessage : ( message ) => {
1299- if ( resumeForChatId !== activeChatIdRef . current ) return ;
1323+ if ( ! isActiveResumeTarget ( { appId : resumeForAppId , chatId : resumeForChatId } ) ) return ;
13001324 if ( shouldCreateResumeAiPlaceholder ( message . event ) ) {
1301- upsertResumeAiPlaceholder ( responseChatId ) ;
1325+ upsertResumeAiPlaceholder ( responseChatId , '' , ChatStatusEnum . loading , {
1326+ resetExistingValue : ! hasPreparedResumeAiRecord
1327+ } ) ;
1328+ hasPreparedResumeAiRecord = true ;
13021329 }
13031330 generatingMessage ( message ) ;
13041331 }
13051332 } ) ;
13061333
1307- if ( resumeForChatId !== activeChatIdRef . current ) return ;
1334+ if ( ! isActiveResumeTarget ( { appId : resumeForAppId , chatId : resumeForChatId } ) ) return ;
13081335
13091336 if ( completedChat ) {
13101337 resumeFinalStatus = completedChat . chatGenerateStatus ;
@@ -1359,7 +1386,7 @@ const ChatBox = ({
13591386 } ) ;
13601387 } catch ( error ) {
13611388 if ( controller . signal . aborted ) return ;
1362- if ( resumeForChatId !== activeChatIdRef . current ) return ;
1389+ if ( ! isActiveResumeTarget ( { appId : resumeForAppId , chatId : resumeForChatId } ) ) return ;
13631390
13641391 const isStreamError = ( error as ResumeStreamErrorType | undefined ) ?. isStreamError === true ;
13651392 resumeFinalStatus = isStreamError
@@ -1404,8 +1431,13 @@ const ChatBox = ({
14041431 } ) ;
14051432 }
14061433 } finally {
1407- resumeController . current = undefined ;
1408- const finishedInActiveChat = activeChatIdRef . current === resumeForChatId ;
1434+ if ( resumeController . current === controller ) {
1435+ resumeController . current = undefined ;
1436+ }
1437+ const finishedInActiveChat = isActiveResumeTarget ( {
1438+ appId : resumeForAppId ,
1439+ chatId : resumeForChatId
1440+ } ) ;
14091441 const leftWhileResuming =
14101442 controller . signal . aborted && isAbortByLeave ( controller . signal . reason ) ;
14111443
@@ -1414,7 +1446,7 @@ const ChatBox = ({
14141446 }
14151447
14161448 setChatBoxData ( ( state ) =>
1417- state . chatId === resumeForChatId
1449+ state . appId === resumeForAppId && state . chatId === resumeForChatId
14181450 ? {
14191451 ...state ,
14201452 chatGenerateStatus : resumeFinalStatus ,
@@ -1425,19 +1457,21 @@ const ChatBox = ({
14251457
14261458 if ( finishedInActiveChat ) {
14271459 void postMarkChatRead ( {
1428- appId,
1460+ appId : resumeForAppId ,
14291461 chatId : resumeForChatId ,
14301462 ...outLinkAuthData
14311463 } )
14321464 . catch ( ( ) => { } )
14331465 . finally ( ( ) => {
14341466 syncSidebarChatGenerateStatus ( resumeFinalStatus , {
1467+ targetAppId : resumeForAppId ,
14351468 hasBeenRead : true ,
14361469 targetChatId : resumeForChatId
14371470 } ) ;
14381471 } ) ;
14391472 } else {
14401473 syncSidebarChatGenerateStatus ( resumeFinalStatus , {
1474+ targetAppId : resumeForAppId ,
14411475 hasBeenRead : false ,
14421476 targetChatId : resumeForChatId
14431477 } ) ;
@@ -1451,9 +1485,12 @@ const ChatBox = ({
14511485 appId ,
14521486 chatId ,
14531487 isChatting ,
1488+ chatBoxData . appId ,
1489+ chatBoxData . chatId ,
14541490 chatBoxData . chatGenerateStatus ,
14551491 generatingMessage ,
14561492 hasMeaningfulAiOutput ,
1493+ isActiveResumeTarget ,
14571494 getResumeUnavailablePlaceholderText ,
14581495 outLinkAuthData ,
14591496 resumeTargetAiDataId ,
0 commit comments