Skip to content

Commit 9be49e1

Browse files
committed
more improvement on visual indicator
1 parent a90e4d7 commit 9be49e1

File tree

2 files changed

+68
-24
lines changed

2 files changed

+68
-24
lines changed

front_end/panels/ai_chat/core/AgentService.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ export class AgentService extends Common.ObjectWrapper.ObjectWrapper<{
127127
// Subscribe to AgentRunner events
128128
AgentRunnerEventBus.getInstance().addEventListener('agent-progress', this.#handleAgentProgress.bind(this));
129129

130-
// Initialize visual indicator system
131-
VisualIndicatorManager.getInstance().initialize();
130+
// Initialize visual indicator system with reference to AgentService
131+
VisualIndicatorManager.getInstance().initialize(this);
132132

133133
// Subscribe to configuration changes
134134
this.#configManager.addChangeListener(this.#handleConfigurationChange.bind(this));

front_end/panels/ai_chat/tools/VisualIndicatorTool.ts

Lines changed: 66 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ function formatToolName(toolName: string): string {
2929
export 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

Comments
 (0)