feat: improve agent activity UI and fix status update propagation
**Agent Activity UI Improvements:** - Create typed discriminated unions for SessionNotification updates - Add AgentActivity component with specialized rendering for each update type - Group consecutive text chunks into single messages (like main chat) - Add collapsible tool call rendering with input/output details - Add plan rendering with task status indicators - Add fallback rendering for unknown activity types (badge + drawer) **Agent Status Update Fix:** - Fix agent killing not updating UI status - Session now detects status change notifications and emits agent_status messages - Agent manager delays agent deletion to allow status updates to propagate - Frontend agent_status handler now receives proper updates **Technical Details:** - Created /packages/app/src/types/agent-activity.ts with typed session updates - Created /packages/app/src/components/agent-activity.tsx with activity renderers - Updated AgentStreamView to use grouped activities with useMemo - Modified session.ts subscribeToAgent to emit agent_status on status changes - Modified agent-manager.ts killAgent to delay deletion for status propagation Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
co-authored by
Claude
Happy
parent
e1e14b1473
commit
674977d6f8
@@ -349,6 +349,9 @@ export class AgentManager {
|
||||
}
|
||||
|
||||
agent.status = "killed";
|
||||
|
||||
// Notify subscribers BEFORE removing from manager
|
||||
// This ensures subscribers can still query agent info
|
||||
this.notifySubscribers(agentId);
|
||||
|
||||
// Kill the process
|
||||
@@ -361,8 +364,11 @@ export class AgentManager {
|
||||
}
|
||||
}, 5000);
|
||||
|
||||
// Remove from manager
|
||||
this.agents.delete(agentId);
|
||||
// Remove from manager after a small delay to allow status updates to propagate
|
||||
setTimeout(() => {
|
||||
this.agents.delete(agentId);
|
||||
console.log(`[Agent ${agentId}] Removed from manager`);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -145,6 +145,41 @@ export class Session {
|
||||
notification: update.notification,
|
||||
},
|
||||
});
|
||||
|
||||
// Check if this is a status change notification
|
||||
// The agent manager sends custom notifications with status field
|
||||
const notification = update.notification as any;
|
||||
if (notification && notification.sessionUpdate && notification.sessionUpdate.status) {
|
||||
const status = notification.sessionUpdate.status;
|
||||
|
||||
// Get current agent info
|
||||
try {
|
||||
const info = this.agentManager!.listAgents().find(a => a.id === agentId);
|
||||
if (info) {
|
||||
// Emit agent_status message
|
||||
this.emit({
|
||||
type: "agent_status",
|
||||
payload: {
|
||||
agentId,
|
||||
status,
|
||||
info: {
|
||||
id: info.id,
|
||||
status: info.status,
|
||||
createdAt: info.createdAt.toISOString(),
|
||||
type: info.type,
|
||||
sessionId: info.sessionId,
|
||||
error: info.error,
|
||||
currentModeId: info.currentModeId,
|
||||
availableModes: info.availableModes,
|
||||
},
|
||||
},
|
||||
});
|
||||
console.log(`[Session ${this.clientId}] Agent ${agentId} status changed to: ${status}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`[Session ${this.clientId}] Failed to get agent info for status update:`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user