@@ -1011,8 +1011,56 @@ const bot = new DiscordBot({
10111011 // ignore
10121012 }
10131013
1014- let postedCount = 0 ;
1014+ let completedCount = 0 ;
10151015 const summaryTasks : Promise < void > [ ] = [ ] ;
1016+
1017+ let pendingThreadName : string | null = null ;
1018+ let threadRenameLoopRunning = false ;
1019+ let threadRenameWaiters : Array < ( ) => void > = [ ] ;
1020+
1021+ const queueThreadNameUpdate = ( name : string ) : void => {
1022+ if ( ! thread ) return ;
1023+ pendingThreadName = name ;
1024+ if ( threadRenameLoopRunning ) return ;
1025+
1026+ threadRenameLoopRunning = true ;
1027+ void ( async ( ) => {
1028+ while ( pendingThreadName ) {
1029+ const nextName = pendingThreadName ;
1030+ pendingThreadName = null ;
1031+
1032+ try {
1033+ await thread ! . setName ( nextName ) ;
1034+ } catch ( err ) {
1035+ logger . warn ( "Failed to update search thread name" , {
1036+ error : err instanceof Error ? err . message : String ( err ) ,
1037+ name : nextName ,
1038+ } ) ;
1039+ }
1040+
1041+ if ( pendingThreadName ) {
1042+ await sleep ( 1100 ) ;
1043+ }
1044+ }
1045+
1046+ threadRenameLoopRunning = false ;
1047+ const waiters = threadRenameWaiters ;
1048+ threadRenameWaiters = [ ] ;
1049+ for ( const resolve of waiters ) {
1050+ resolve ( ) ;
1051+ }
1052+ } ) ( ) ;
1053+ } ;
1054+
1055+ const waitForThreadNameUpdates = async ( ) : Promise < void > => {
1056+ if ( ! thread || ( ! threadRenameLoopRunning && ! pendingThreadName ) ) {
1057+ return ;
1058+ }
1059+ await new Promise < void > ( ( resolve ) => {
1060+ threadRenameWaiters . push ( resolve ) ;
1061+ } ) ;
1062+ } ;
1063+
10161064 for ( const p of parsed ) {
10171065 // Post a lightweight placeholder message quickly so the UI reflects
10181066 // progress immediately. Generate the (potentially slow) summary in
@@ -1054,8 +1102,6 @@ const bot = new DiscordBot({
10541102 logger . warn ( "Failed to post search result placeholder" , { error : err instanceof Error ? err . message : String ( err ) } ) ;
10551103 }
10561104
1057- postedCount ++ ;
1058-
10591105 // Kick off summary generation in background so slow summaries don't
10601106 // block the main loop. We track tasks to set the final thread title
10611107 // once all summaries have completed.
@@ -1114,26 +1160,20 @@ const bot = new DiscordBot({
11141160 // ignore
11151161 }
11161162 }
1163+
1164+ completedCount ++ ;
1165+ queueThreadNameUpdate ( `Searching: '${ query } ' (${ completedCount } /${ parsed . length } )` ) ;
11171166 } ) ( ) ;
11181167 summaryTasks . push ( task ) ;
1119-
1120- // Best-effort, non-blocking progress title update. Do not await this
1121- // call in the loop because Discord thread rename throttling can
1122- // otherwise delay summary generation and make placeholders appear
1123- // stuck at "Generating summary...".
1124- if ( thread ) {
1125- void thread . setName ( `Searching: '${ query } ' (${ postedCount } /${ parsed . length } )` ) . catch ( ( ) => {
1126- // ignore
1127- } ) ;
1128- }
11291168 }
11301169
11311170 void ( async ( ) => {
11321171 await Promise . allSettled ( summaryTasks ) ;
11331172
11341173 try {
11351174 if ( thread ) {
1136- await thread . setName ( `Search results for '${ query } ':` ) ;
1175+ queueThreadNameUpdate ( `Search results for '${ query } '` ) ;
1176+ await waitForThreadNameUpdates ( ) ;
11371177 }
11381178 } catch {
11391179 // ignore
0 commit comments