feat(web): hide subagent threads from user-facing thread lists (5/5) - #4664
feat(web): hide subagent threads from user-facing thread lists (5/5)#4664shivamhwp wants to merge 1 commit into
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
940e8fb to
c3a50f8
Compare
d2ef6c7 to
adb1e9b
Compare
c3a50f8 to
8c6a796
Compare
adb1e9b to
39912b0
Compare
There was a problem hiding this comment.
🟡 Medium
t3code/apps/web/src/components/chat/ThreadRelationshipsControl.tsx
Lines 127 to 129 in 39912b0
When a user-facing thread's only relationships are subagent edges, the .filter((relationship) => relationship.edge.kind !== "subagent") call empties relationshipRows, causing the early return null at line 127 to hide the entire panel — including the "Disconnect agent session" menu. So even when canDetach is true, the user cannot stop the provider session from this panel. The canDetach check and its menu are computed before the early return but are never rendered because the return short-circuits first. Consider gating the early return on the absence of both relationship rows and a detachable session, or rendering the session controls independently of the relationship list.
- if (relationshipRows.length === 0) {
- return null;
- }
+ if (relationshipRows.length === 0 && !canDetach) {
+ return null;
+ }🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @apps/web/src/components/chat/ThreadRelationshipsControl.tsx around lines 127-129:
When a user-facing thread's only relationships are subagent edges, the `.filter((relationship) => relationship.edge.kind !== "subagent")` call empties `relationshipRows`, causing the early `return null` at line 127 to hide the entire panel — including the "Disconnect agent session" menu. So even when `canDetach` is true, the user cannot stop the provider session from this panel. The `canDetach` check and its menu are computed before the early return but are never rendered because the return short-circuits first. Consider gating the early return on the absence of both relationship rows and a detachable session, or rendering the session controls independently of the relationship list.
8c6a796 to
103b937
Compare
39912b0 to
6bc3a8d
Compare
103b937 to
31adb36
Compare
6bc3a8d to
05fe44c
Compare
31adb36 to
b270c47
Compare
05fe44c to
7458298
Compare
A subagent's child thread is an implementation detail of the agent that owns it, not a conversation the user started. Listing them alongside real threads makes the sidebar grow with every delegation. Filtered at the source — the shell snapshot the server serves — so every client sees the same set rather than each re-deriving it. The web client filters again for locally-held state, and the thread route redirects to the parent if a subagent thread is reached directly. Mobile is part of the sweep, not left behind. It still offered "Open subagent thread" and had no redirect to fall back on, so it would have navigated to a thread the client no longer receives. Its relationships banner also needed the same subagent-edge filter web has: those edges are derived from the projection rather than from thread shells, so they survive the shell filtering and would have rendered as "Unavailable" — and, sorting first, could have taken over the banner headline. Trade-off worth stating plainly: a subagent's transcript becomes unreachable. The Agents panel added in the previous PR shows what an agent did and what it returned, but not its full conversation. That is the intended shape here, and the "Open subagent thread" affordances are removed on both clients rather than left as dead ends.
b270c47 to
daf1a88
Compare
7458298 to
4daeac4
Compare
Last of five stacked PRs replacing #4551. Stacked on #4663 — review that first.
A subagent's child thread is an implementation detail of the agent that owns it, not a conversation the user started. Listing them alongside real threads makes the sidebar grow with every delegation.
Filtered at the source — the shell snapshot the server serves — so every client sees the same set rather than each re-deriving it. The web client filters again for locally-held state, and the thread route redirects to the parent if a subagent thread is reached directly.
Mobile is part of the sweep
Found in review, and the reason this isn't a web-only change. Mobile still offered "Open subagent thread" with no redirect to fall back on, so it would have navigated to a thread the client no longer receives. Its relationships banner also needed the same subagent-edge filter web has — those edges derive from the projection rather than from thread shells, so they survive the shell filtering and would have rendered as "Unavailable", and by sorting first could have taken over the banner headline.
The trade-off, stated plainly
A subagent's transcript becomes unreachable. The Agents panel from #4663 shows what an agent did and what it returned, but not its full conversation. That is the intended shape here, and the "Open subagent thread" affordances are removed on both clients rather than left as dead ends — but it is a real capability loss and worth a deliberate decision rather than being smuggled in with a sidebar tidy-up.
Testing
Typecheck clean on server, web, client-runtime. Server 1,685 passing, web 1,500 passing, client-runtime 485 passing. (
apps/mobilehas 70 pre-existing typecheck errors on the base branch, unchanged by this PR.)Known, not fixed here
/rather than the parent. It matters under version skew, so it is kept.entities.tsswaps memoized ref atoms for per-call filter+map. The cost is negligible but the identity stability is not; filtering inside the client-runtime atoms instead would be the better shape.thread.removeddelta, absorbed harmlessly by the reducer.Note
Hide internal subagent threads from all user-facing thread lists and navigation
isInternalSubagentThreadandisUserFacingThreadhelpers that classify both lineage-subagent and node-owned subagent threads as internal.userFacingShellSnapshotutility in ThreadManagementService.ts./) in _chat.$environmentId.$threadId.tsx.findThreadRefnow returns nothing for internal subagent thread IDs, which could silently break any code that attempts to look up a subagent thread by ID.📊 Macroscope summarized 6bc3a8d. 12 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted
(Automatic summaries will resume when PR exits draft mode or review begins).🗂️ Filtered Issues
No issues evaluated.