@@ -29,6 +29,7 @@ function formatToolName(toolName: string): string {
2929export class VisualIndicatorManager {
3030 private static instance : VisualIndicatorManager | null = null ;
3131 private eventBus : AgentRunnerEventBus ;
32+ private agentService : any | null = null ; // AgentService reference for checking running state
3233 private isActive = false ;
3334 private currentSessionId : string | null = null ;
3435 private currentAgentName : string | null = null ;
@@ -48,10 +49,11 @@ export class VisualIndicatorManager {
4849 }
4950
5051 /**
51- * Initialize the visual indicator system
52+ * Initialize the visual indicator system with AgentService reference
5253 */
53- initialize ( ) : void {
54- logger . info ( 'Visual indicator system initialized' ) ;
54+ initialize ( agentService : any ) : void {
55+ this . agentService = agentService ;
56+ logger . info ( 'Visual indicator system initialized with AgentService' ) ;
5557 this . setupEventListeners ( ) ;
5658 this . setupNavigationListener ( ) ;
5759 }
@@ -179,6 +181,27 @@ export class VisualIndicatorManager {
179181 }
180182 }
181183
184+ /**
185+ * Check if any agent is currently running (source of truth from AgentService)
186+ */
187+ private hasAnyRunningAgent ( ) : boolean {
188+ if ( ! this . agentService ) {
189+ logger . warn ( '[VisualIndicator] No AgentService - cannot check running state' ) ;
190+ return false ;
191+ }
192+
193+ const activeSessions = this . agentService . getActiveAgentSessions ( ) ;
194+ const hasRunning = activeSessions . some ( ( session : any ) => session . status === 'running' ) ;
195+
196+ logger . info ( '[VisualIndicator] Running agent check:' , {
197+ totalSessions : activeSessions . length ,
198+ hasRunning,
199+ sessionStates : activeSessions . map ( ( s : any ) => ( { id : s . sessionId , status : s . status } ) )
200+ } ) ;
201+
202+ return hasRunning ;
203+ }
204+
182205 /**
183206 * Notify that a session has completed (call from AgentService)
184207 */
@@ -189,9 +212,12 @@ export class VisualIndicatorManager {
189212 // Clean up stored tool info for this session
190213 this . currentToolInfo . delete ( sessionId ) ;
191214
192- // Hide indicators when no more active sessions (regardless of which one completed)
193- if ( this . activeSessions . size === 0 ) {
215+ // Check if any agent is still running (source of truth from AgentService)
216+ if ( ! this . hasAnyRunningAgent ( ) ) {
217+ logger . info ( '[VisualIndicator] No agents running - hiding indicators' ) ;
194218 await this . hideIndicators ( ) ;
219+ } else {
220+ logger . info ( '[VisualIndicator] Other agents still running - keeping indicators visible' ) ;
195221 }
196222 }
197223
@@ -268,6 +294,7 @@ export class VisualIndicatorManager {
268294 }
269295
270296 html.devtools-agent-active {
297+ min-height: 100vh;
271298 animation: devtools-agent-glow 2s ease-in-out infinite;
272299 }
273300
@@ -280,56 +307,65 @@ export class VisualIndicatorManager {
280307 backdrop-filter: blur(16px) saturate(180%);
281308 -webkit-backdrop-filter: blur(16px) saturate(180%);
282309 color: white;
283- padding: 16px 28px 18px 28px ;
284- border-radius: 12px ;
310+ padding: 12px 20px 14px 20px ;
311+ border-radius: 10px ;
285312 border: 1px solid rgba(0, 164, 254, 0.25);
286313 border-top: 2px solid rgba(0, 164, 254, 0.6);
287314 box-shadow:
288315 0 8px 32px rgba(0, 0, 0, 0.4),
289316 0 2px 8px rgba(0, 0, 0, 0.2),
290317 inset 0 1px 0 rgba(255, 255, 255, 0.1);
291- z-index: 999999 ;
318+ z-index: 2147483647 ;
292319 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
293- font-size: 14px ;
294- max-width: 620px ;
295- min-width: 320px ;
320+ font-size: 12px ;
321+ max-width: 520px ;
322+ min-width: 280px ;
296323 opacity: 0;
297324 transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
298- pointer-events: none;
325+ pointer-events: auto;
326+ cursor: default;
299327 }
300328
301329 #devtools-agent-indicator.visible {
302330 opacity: 1;
303331 transform: translateX(-50%) translateY(0);
304332 }
305333
334+ #devtools-agent-indicator.visible:hover {
335+ opacity: 0.15;
336+ background: linear-gradient(135deg, rgba(0, 20, 40, 0.15) 0%, rgba(0, 10, 30, 0.1) 100%);
337+ backdrop-filter: blur(4px) saturate(120%);
338+ -webkit-backdrop-filter: blur(4px) saturate(120%);
339+ transition: all 0.2s ease-out;
340+ }
341+
306342 .devtools-agent-name {
307343 display: flex;
308344 align-items: center;
309345 font-weight: 600;
310- font-size: 16px ;
346+ font-size: 14px ;
311347 color: #4fc3f7;
312- margin-bottom: 8px ;
313- padding-bottom: 8px ;
348+ margin-bottom: 6px ;
349+ padding-bottom: 6px ;
314350 border-bottom: 1px solid rgba(255, 255, 255, 0.08);
315351 text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
316352 letter-spacing: 0.3px;
317353 }
318354
319355 .devtools-agent-action {
320356 font-weight: 500;
321- font-size: 14px ;
322- margin-bottom: 6px ;
357+ font-size: 12px ;
358+ margin-bottom: 4px ;
323359 color: rgba(255, 255, 255, 0.95);
324360 text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
325361 line-height: 1.5;
326362 }
327363
328364 .devtools-agent-reasoning {
329- font-size: 12px ;
365+ font-size: 10px ;
330366 color: rgba(255, 255, 255, 0.7);
331367 font-style: italic;
332- margin-top: 6px ;
368+ margin-top: 4px ;
333369 line-height: 1.5;
334370 padding-left: 2px;
335371 }
@@ -340,8 +376,8 @@ export class VisualIndicatorManager {
340376
341377 .devtools-agent-spinner {
342378 display: inline-block;
343- width: 15px ;
344- height: 15px ;
379+ width: 13px ;
380+ height: 13px ;
345381 border: 2.5px solid rgba(79, 195, 247, 0.25);
346382 border-top-color: #4fc3f7;
347383 border-radius: 50%;
@@ -439,6 +475,7 @@ export class VisualIndicatorManager {
439475 // Extract agent name from event and update current state
440476 const rawAgentName = event . agentName || this . currentAgentName || 'AI Agent' ;
441477 const agentName = formatToolName ( rawAgentName ) ;
478+
442479 if ( event . agentName ) {
443480 this . currentAgentName = event . agentName ;
444481 }
@@ -451,7 +488,14 @@ export class VisualIndicatorManager {
451488 const toolCall = event . data . toolCall ;
452489 const toolName = toolCall . content ?. toolName || 'tool' ;
453490 const formattedToolName = formatToolName ( toolName ) ;
454- let toolReasoning = toolCall . content ?. reasoning || '' ;
491+
492+ // Extract reasoning from multiple sources (matching UI pattern)
493+ // Priority: 1) LLM reasoning (O-models), 2) toolArgs.reasoning (most common), 3) fallback aliases
494+ const toolArgs = toolCall . content ?. toolArgs || { } ;
495+ const reasonFromArgs = toolArgs ?. reasoning ?? toolArgs ?. reason ;
496+ let toolReasoning = toolCall . content ?. reasoning ||
497+ ( reasonFromArgs !== undefined ? String ( reasonFromArgs ) : '' ) ||
498+ '' ;
455499
456500 // Fallback: if the provider didn't return reasoning, try the latest session reasoning message
457501 if ( ! toolReasoning && event . data ?. session ?. messages && Array . isArray ( event . data . session . messages ) ) {
0 commit comments