Skip to content

Fix: Render an expanded subagent block's rows together under its header - #1614

Open
huang195 wants to merge 3 commits into
rossoctl:mainfrom
huang195:fix/subagent-block-expand
Open

huang195 wants to merge 3 commits into
rossoctl:mainfrom
huang195:fix/subagent-block-expand

Conversation

@huang195

@huang195 huang195 commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

What

Two changes to the subagent blocks from #1601, from its live check on session
3230ebba ("Cortex PR 1611 Merge Conflict"):

  1. An expanded block's rows render together, under its header — pulled out
    of the chronological interleaving with the main conversation.
  2. Member exchanges are numbered from 1 within the block, while main rows
    keep session-wide numbers.

Why

Expanding ▾─ review cortex#1611 r1 worked, but the rows directly under the
header were the main conversation's — a subagent's exchange spans several
main-conversation turns (and other subagents'), so its rows scattered across
the pane at their own timestamps. That reads as "expanding did nothing". And
the # numbers the members did show were session-wide (starting at 94), which
says nothing about how much the subagent itself did — the block reads as the
subagent's own transcript, so its first message should be 1.

The merged tests' fixture never interleaved a main row inside a subagent
exchange, so the interleaved case was never pinned.

The changes

Contiguity — rebuildEventsTable's row loop: when a block's header is
emitted and the block is open, all of b.rows (already the inactive-filtered
population, in arrival order) render immediately after the header; member rows
no longer render at their own loop turn. Cell building moved into a small
renderEventRow(j) helper used by both paths so rows / visibleRows /
search rows cannot drift apart. Membership is by subagent id over the whole
session, not time-contiguity, so interleaving cannot split a block into
segments or emit a second header for the same agent — pinned by
TestBlocks_ConcurrentSubagentsEachStayOneSegment (two subagents interleaved
with each other and the main conversation, one resuming long after it started).

Numbering — a block-local blockIDs map renumbers member exchanges from 1,
built after the blocks are collected; the session-wide ids still decide what an
exchange IS (request + response share one number), only the counting restarts
per block. The header's rollup counts the same unit (28 msgs, not 56 rows)
so it agrees with the last number shown inside the block.

Unchanged: the header anchors at the block's first surviving row; main rows
keep their positions and session numbers; TIME stays absolute; the DIR
gutter's │ still marks members; sorting disables grouping (blocks exist only
in the chronological view, so the sort-key path never sees a member row);
cursor pin, search, hideInactive and the Timeline reveal all key on
visibleRows/event identity, not row order — # is display-only.

Verification

  • New tests: TestBlocks_ExpandedMembersStayTogether (a main row
    chronologically inside a subagent's exchange stays outside the expanded
    block), TestBlocks_ConcurrentSubagentsEachStayOneSegment,
    TestBlocks_MembersNumberFromOneInsideTheBlock (member # cells read
    1,1,2,2 and main rows keep 1..3; header says 2 msgs). All fail on main's
    behavior where they apply.
  • Full cmd/agentop/tui package green; gofmt/go vet clean.
  • Drove the built binary headless against the live proxy on the original
    session: Enter on ▸─ review cortex#1611 r1 · 28 msgs → ▾, the rows under
    the header are all the subagent's glm exchanges numbered 1,1,2,2,3…, no
    main-conversation rows interleaved; r2 (34 msgs) stays collapsed.

Assisted-By: Claude (Anthropic AI) noreply@anthropic.com

An open block's member rows rendered at their own chronological
positions, interleaved with the main conversation's — so expanding a
header left the rows directly under it belonging to the main
conversation, which read as the expansion doing nothing (rossoctl#1047 live
check). The block's rows now render contiguously under the header, in
arrival order within the block; the TIME and # columns still carry
where each row sat, and the DIR gutter's │ still marks members.

Blocks exist only in the chronological view (a sort disables
grouping), so the sort-key path never sees a member row.

Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: Hai Huang <huang195@gmail.com>
@huang195
huang195 requested a review from a team as a code owner October 30, 2026 16:41
@coderabbitai

coderabbitai Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 25 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 98fa8b74-a5d2-4727-a230-2857825a20b1
Commits

Reviewing files that changed from the base of the PR and between 5b91db4 and 1dd7cfb.

Files selected for processing: 5
  • CLAUDE.md
  • cmd/agentop/tui/events_blocks.go
  • cmd/agentop/tui/events_blocks_test.go
  • cmd/agentop/tui/events_columns.go
  • cmd/agentop/tui/events_pane.go
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Two subagents interleaved with each other and with the main
conversation, one resuming long after it started: each block still
renders its whole run contiguously under its own single header —
membership is by subagent id over the whole session, not by
time-contiguity, so interleaving cannot split a block or emit a second
header for the same agent.

Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: Hai Huang <huang195@gmail.com>
The block reads as the subagent's own transcript, so its first
exchange is 1 — the session-wide number the main rows keep would
start a block at 94 and say nothing about how much the subagent
itself did. A request and its response still share one number (the
session-wide ids still decide what an exchange is; only the counting
restarts per block), and the header's rollup counts the same unit
(28 msgs, not 56 rows) so it agrees with the last number shown
inside the block.

Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: Hai Huang <huang195@gmail.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: New/ToDo

Development

Successfully merging this pull request may close these issues.

1 participant