@@ -1423,6 +1423,7 @@ <h3>Cost Breakdown</h3>
14231423 let expandedToolInputs = new Set ( ) ;
14241424 let expandedOutputs = new Set ( ) ;
14251425 let turnsSearchQuery = '' ;
1426+ let turnsSearchTimer = null ;
14261427
14271428 function fmtTime ( iso ) {
14281429 if ( ! iso ) return '' ;
@@ -1463,17 +1464,15 @@ <h3>Cost Breakdown</h3>
14631464 const query = turnsSearchQuery . toLowerCase ( ) ;
14641465 const turns = query
14651466 ? allTurns . filter ( t => {
1466- // Search in text content, tool names, tool inputs, and results
1467+ if ( t . toolCalls && t . toolCalls . some ( tc => tc . toLowerCase ( ) . includes ( query ) ) ) return true ;
14671468 for ( const c of ( t . content || [ ] ) ) {
14681469 if ( c . text && c . text . toLowerCase ( ) . includes ( query ) ) return true ;
14691470 if ( c . toolName && c . toolName . toLowerCase ( ) . includes ( query ) ) return true ;
1470- if ( c . toolInput && JSON . stringify ( c . toolInput ) . toLowerCase ( ) . includes ( query ) ) return true ;
14711471 if ( c . toolResult ) {
14721472 if ( c . toolResult . stdout && c . toolResult . stdout . toLowerCase ( ) . includes ( query ) ) return true ;
14731473 if ( c . toolResult . stderr && c . toolResult . stderr . toLowerCase ( ) . includes ( query ) ) return true ;
14741474 }
14751475 }
1476- if ( t . toolCalls && t . toolCalls . some ( tc => tc . toLowerCase ( ) . includes ( query ) ) ) return true ;
14771476 return false ;
14781477 } )
14791478 : allTurns ;
@@ -1664,15 +1663,17 @@ <h3>Cost Breakdown</h3>
16641663 } ) ;
16651664 } ) ;
16661665
1667- // Search input
1666+ // Search input (debounced)
16681667 const searchInput = document . getElementById ( 'turns-search-input' ) ;
16691668 if ( searchInput ) {
16701669 searchInput . addEventListener ( 'input' , ( e ) => {
1671- turnsSearchQuery = e . target . value ;
1672- renderTurns ( ) ;
1673- // Re-focus and restore cursor position
1674- const el = document . getElementById ( 'turns-search-input' ) ;
1675- if ( el ) { el . focus ( ) ; el . selectionStart = el . selectionEnd = el . value . length ; }
1670+ clearTimeout ( turnsSearchTimer ) ;
1671+ turnsSearchTimer = setTimeout ( ( ) => {
1672+ turnsSearchQuery = e . target . value ;
1673+ renderTurns ( ) ;
1674+ const el = document . getElementById ( 'turns-search-input' ) ;
1675+ if ( el ) { el . focus ( ) ; el . selectionStart = el . selectionEnd = el . value . length ; }
1676+ } , 250 ) ;
16761677 } ) ;
16771678 }
16781679 }
@@ -2272,6 +2273,7 @@ <h3>Cost Breakdown</h3>
22722273 }
22732274
22742275 // ---- SSE Connection ----
2276+ let sseDetailTimer = null ;
22752277 function connectSSE ( ) {
22762278 const evtSource = new EventSource ( '/api/events' ) ;
22772279 evtSource . onmessage = ( event ) => {
@@ -2286,25 +2288,28 @@ <h3>Cost Breakdown</h3>
22862288 } ) ;
22872289 updateProjectDropdown ( ) ;
22882290 renderSidebar ( ) ;
2289- // Re-fetch and re-render detail for selected session
2291+ // Re-fetch and re-render detail for selected session (debounced)
22902292 if ( selectedId ) {
22912293 const s = allSessions . find ( s => s . id === selectedId ) ;
22922294 if ( s ) {
22932295 renderHeader ( ) ;
2294- fetch ( '/api/sessions/' + encodeURIComponent ( selectedId ) )
2295- . then ( r => r . ok ? r . json ( ) : null )
2296- . then ( detail => {
2297- if ( detail && selectedId === detail . id ) {
2298- selectedDetail = detail ;
2299- if ( activeTab === 'overview' ) renderOverview ( ) ;
2300- else if ( activeTab === 'turns' ) renderTurns ( ) ;
2301- else if ( activeTab === 'tools' ) renderTools ( ) ;
2302- else if ( activeTab === 'subagents' ) renderSubagents ( ) ;
2303- else if ( activeTab === 'skills' ) renderSkills ( ) ;
2304- else if ( activeTab === 'flow' ) renderFlow ( ) ;
2305- }
2306- } )
2307- . catch ( ( ) => { } ) ;
2296+ clearTimeout ( sseDetailTimer ) ;
2297+ sseDetailTimer = setTimeout ( ( ) => {
2298+ fetch ( '/api/sessions/' + encodeURIComponent ( selectedId ) )
2299+ . then ( r => r . ok ? r . json ( ) : null )
2300+ . then ( detail => {
2301+ if ( detail && selectedId === detail . id ) {
2302+ selectedDetail = detail ;
2303+ if ( activeTab === 'overview' ) renderOverview ( ) ;
2304+ else if ( activeTab === 'turns' ) renderTurns ( ) ;
2305+ else if ( activeTab === 'tools' ) renderTools ( ) ;
2306+ else if ( activeTab === 'subagents' ) renderSubagents ( ) ;
2307+ else if ( activeTab === 'skills' ) renderSkills ( ) ;
2308+ else if ( activeTab === 'flow' ) renderFlow ( ) ;
2309+ }
2310+ } )
2311+ . catch ( ( ) => { } ) ;
2312+ } , 500 ) ;
23082313 }
23092314 }
23102315 } catch ( e ) {
0 commit comments