Skip to content

Handle agent management view updates based on event type#9866

Merged
lucieleblanc merged 5 commits intomasterfrom
lucie/app-4329-agent-management-update-handling
May 4, 2026
Merged

Handle agent management view updates based on event type#9866
lucieleblanc merged 5 commits intomasterfrom
lucie/app-4329-agent-management-update-handling

Conversation

@lucieleblanc
Copy link
Copy Markdown
Contributor

@lucieleblanc lucieleblanc commented May 1, 2026

Description

The "Runs" agent management view was rebuilding its entire card list every time any conversation's status changed. While an agent is streaming, status events fire many times per second, and a recent heap profile attributed over 2 GB of allocations (plus ~700 MB of allocator churn) to this rebuild path.

Most of those events don't actually change the visible list: they re-emit the same status (typical during streaming) or change the status within the same active-filter bucket. In both cases the list doesn't need to rebuild — cards read their status fresh at render time, and on this path (local conversations) the action buttons don't depend on status.

This PR makes the agent management view branch on the typed payload introduced in #9864:

  • Restored: no card-visible change. Only refresh the open details panel.
  • Status set crossing the active filter: full rebuild, since membership in the visible list changed.
  • Status set in the same bucket (or All filter): refresh the open details panel and re-render so the status icon picks up the new value. No list rebuild and no per-card work.

A small StatusFilter::is_membership_crossed helper centralizes the "did this status transition cross the active filter?" check.

This PR also drops the conversation_id field from the ConversationUpdated event, since no subscriber needs it now that the view doesn't target a specific card on this path.

Testing

Started a conversation in the background. Opened the agent management view with the All filter selected and confirmed:

  • The list doesn't re-sort while the agent is streaming.
  • Toggling the status filter across the Working/Done/Failed boundary still updates the visible cards.

Server API dependencies

No server dependencies.

Agent Mode

  • Warp Agent Mode - This PR was created via Warp's AI Agent Mode

Changelog Entries for Stable

CHANGELOG-IMPROVEMENT: Reduced memory usage and CPU work in the agent runs management view while a conversation is streaming.

@cla-bot cla-bot Bot added the cla-signed label May 1, 2026
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 1, 2026

@lucieleblanc

I'm starting a first review of this pull request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

This PR optimizes the agent management Runs view by routing conversation update events through targeted card refreshes instead of rebuilding the full card list for every status update.

Concerns

  • Same-bucket status re-emissions still take the targeted card-update path, so the streaming hot path continues to scan visible cards and rebuild button config on every event rather than becoming a no-op.
  • This is a user-visible Runs view behavior change, but the PR description does not include screenshots or video evidence. For faster review, please upload screenshots or a video of the feature working end to end.

Verdict

Found: 0 critical, 2 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Comment thread app/src/ai/agent_management/view.rs Outdated
self.get_tasks_from_model(ctx);
self.refresh_details_panel_if_needed(ctx);
} else {
self.update_card_for_conversation(conversation_id, ctx);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] Same-bucket re-emissions still reach this path, so repeated InProgress status sets scan self.items and rebuild the card button config on every streaming event; make exact status re-emissions a no-op before calling update_card_for_conversation (or carry enough previous/new status detail to distinguish re-emits from real same-bucket changes).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixing

@liliwilson liliwilson self-requested a review May 3, 2026 05:06
Copy link
Copy Markdown
Contributor

@liliwilson liliwilson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for fixing!! 🙌

Comment thread app/src/ai/agent_management/view.rs Outdated

/// Update the action-buttons config for the card backing a given conversation, without
/// rebuilding the entire list. If no matching card is currently visible, this is a no-op.
fn update_card_for_conversation(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't actually think this function is necessary—we read the status for the card at render time, so if we haven't crossed a filter boundary, we shouldn't actually need to rebuild the card at all. A status change for a local conversation (which is the only type triggered from the BlocklistAIHistoryModel) won't change the action buttons available, so we should be good to just refresh the details panel in the else branch above

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, thank you!

/// whether an item is included by this filter. `All` matches every bucket so it
/// is never crossed; the other variants are crossed when exactly one of the buckets
/// equals this filter.
pub(crate) fn is_membership_crossed(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@peicodes peicodes mentioned this pull request May 4, 2026
@lucieleblanc lucieleblanc force-pushed the lucie/app-4329-agent-management-update-handling branch from 6b6b815 to 94885be Compare May 4, 2026 16:55
@lucieleblanc lucieleblanc force-pushed the lucie/app-4329-conversation-update-details branch from 6b2457e to 2dfff48 Compare May 4, 2026 17:06
Base automatically changed from lucie/app-4329-conversation-update-details to master May 4, 2026 17:27
@lucieleblanc lucieleblanc force-pushed the lucie/app-4329-agent-management-update-handling branch from 94885be to edc0230 Compare May 4, 2026 18:07
@lucieleblanc lucieleblanc merged commit 2258cd3 into master May 4, 2026
24 checks passed
@lucieleblanc lucieleblanc deleted the lucie/app-4329-agent-management-update-handling branch May 4, 2026 20:43
wolverine2k pushed a commit to wolverine2k/warp that referenced this pull request May 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants