refactor(desktop): extract the channel agent session surface from ChannelPane

**Category:** refactor

The file-size ratchet grandfathers `ChannelPane.tsx` above the 1000-line cap
but forbids growth, and `#6575` landed it at 1011 lines on main — so this
branch's +35 became a hard gate failure on rebase rather than the +35 it was
when the branch was cut.

Extracting rather than trimming, and specifically extracting *this branch's*
own additions rather than anything `#6575` just added: the agent-session
branch of the auxiliary-surface chain moves into
`ChannelAgentSessionSurface`, taking the cross-channel re-scoping rule, the
cover-drawer-vs-split-pane choice, and its layout-prop resolution with it.
`ChannelPane` keeps what it owns — the surface resolution, the shared
`AnimatePresence` key, and the split pane's resize affordances, which it
passes down as `wrapSplitPane`.

No behaviour change: the same panel with the same props in both
presentations. `ChannelPane.tsx` is now 1006 lines, back under the ratchet's
recorded 1011.

Signed-off-by: ss-dev-00 <a02c4e0850e5e612b4ddf95dbe2f5c56467cf27c6552203bc833ff438fb31971@buzz.block.builderlab.xyz>
Co-authored-by: Bradley Axen <baxen@squareup.com>
Signed-off-by: Bradley Axen <baxen@squareup.com>
This commit is contained in:
ss-dev-00
2026-08-24 14:54:10 -07:00
committed by Rizz
parent 5aae5c5bfd
commit e02cd6b62f
2 changed files with 127 additions and 61 deletions

View File

@@ -0,0 +1,105 @@
import type * as React from "react";
import * as agentSessionSelection from "@/features/channels/ui/agentSessionSelection";
import type { ChannelAgentSessionAgent } from "@/features/channels/ui/useChannelAgentSessions";
import { getAgentSessionPanelPresentation } from "@/features/channels/lib/agentSessionPanelPresentation";
import { AgentActivityDrawer } from "@/features/channels/ui/AgentActivityDrawer";
import { AgentSessionThreadPanel } from "@/features/channels/ui/AgentSessionThreadPanel";
import type { BotActivityAgent } from "@/features/channels/ui/BotActivityBar";
import type { UserProfileLookup } from "@/features/profile/lib/identity";
import type { Channel } from "@/shared/api/types";
type ChannelAgentSessionSurfaceProps = {
activeChannel: Channel;
activeChannelId: string | null;
activityAgents: BotActivityAgent[];
agent: ChannelAgentSessionAgent;
/** Render the panel inside the cover drawer instead of the split pane. */
isCoverDrawer: boolean;
isSinglePanelView: boolean;
onBack?: () => void;
onClose: () => void;
openAgentSessionChannelId: string | null;
profiles?: UserProfileLookup;
useSplitAuxiliaryPane: boolean;
widthPx: number;
/**
* Applies the split-pane presentation, including its resize affordances.
* Supplied by `ChannelPane` because that pane owns the resize state; the
* cover-drawer presentation is applied here.
*/
wrapSplitPane: (panel: React.ReactNode) => React.ReactNode;
};
/**
* The channel's agent activity surface: the session panel plus the channel
* re-scoping its content and actions depend on.
*
* Split out of `ChannelPane` so the re-scoping rule below has one home and is
* not another branch inside that component's auxiliary-surface chain. Which
* presentation this lands in is decided upstream and applied through `wrap`.
*/
export function ChannelAgentSessionSurface({
activeChannel,
activeChannelId,
activityAgents,
agent,
isCoverDrawer,
isSinglePanelView,
onBack,
onClose,
openAgentSessionChannelId,
profiles,
useSplitAuxiliaryPane,
widthPx,
wrapSplitPane,
}: ChannelAgentSessionSurfaceProps) {
// When the panel was opened from a different channel than the currently
// active one, re-scope it to the active channel so that both the
// content/header AND channel-backed actions (e.g. Stop current turn) operate
// on the same channel object.
const effectiveAgentSessionChannelId =
openAgentSessionChannelId && activeChannel.id !== openAgentSessionChannelId
? activeChannelId
: openAgentSessionChannelId;
const channel = effectiveAgentSessionChannelId
? effectiveAgentSessionChannelId === activeChannel.id
? activeChannel
: null
: agentSessionSelection.isAgentInActivityList({
activityAgents,
selectedAgent: agent,
})
? activeChannel
: null;
const layoutProps = getAgentSessionPanelPresentation({
isCoverDrawer,
isSinglePanelView,
useSplitAuxiliaryPane,
});
const panel = (
<AgentSessionThreadPanel
agent={agent}
canInterruptTurn={agent.canInterruptTurn}
channel={channel}
channelId={effectiveAgentSessionChannelId}
{...layoutProps}
profiles={profiles}
onBack={onBack}
onClose={onClose}
widthPx={widthPx}
/>
);
return isCoverDrawer ? (
<AgentActivityDrawer
channelName={activeChannel.name ?? "channel"}
onClose={onClose}
>
{panel}
</AgentActivityDrawer>
) : (
wrapSplitPane(panel)
);
}

View File

@@ -25,16 +25,12 @@ import {
import { buildVideoReviewPresentationByMessageId } from "@/features/messages/lib/videoReviewContext";
import { useComposerHeightPadding } from "@/features/messages/ui/useComposerHeightPadding";
import { UserProfilePanel } from "@/features/profile/ui/UserProfilePanel";
import { AgentSessionThreadPanel } from "@/features/channels/ui/AgentSessionThreadPanel";
import { ChannelManagementAuxiliaryPanel } from "@/features/channels/ui/ChannelManagementAuxiliaryPanel";
import { RightAuxiliaryPane } from "@/features/channels/ui/RightAuxiliaryPane";
import { ThreadViewModeToggle } from "@/features/channels/ui/ThreadViewModeToggle";
import { AgentActivityDrawer } from "@/features/channels/ui/AgentActivityDrawer";
import { ChannelAgentSessionSurface } from "@/features/channels/ui/ChannelAgentSessionSurface";
import { FocusThreadDrawer } from "@/features/channels/ui/FocusThreadDrawer";
import {
AGENT_SESSION_SURFACE_KEY,
getAgentSessionPanelPresentation,
} from "@/features/channels/lib/agentSessionPanelPresentation";
import { AGENT_SESSION_SURFACE_KEY } from "@/features/channels/lib/agentSessionPanelPresentation";
import {
resolveChannelAuxiliarySurface,
resolveChannelCoverDrawer,
@@ -534,20 +530,10 @@ export const ChannelPane = React.memo(function ChannelPane({
) : (
wrapAux(panel, "message-thread-panel", { key: THREAD_SURFACE_KEY })
);
const wrapAgentSessionPanel = (panel: React.ReactNode) =>
useAgentActivityDrawer ? (
<AgentActivityDrawer
channelName={activeChannel?.name ?? "channel"}
key={AGENT_SESSION_SURFACE_KEY}
onClose={onCloseAgentSession}
>
{panel}
</AgentActivityDrawer>
) : (
wrapAux(panel, "agent-session-thread-panel", {
key: AGENT_SESSION_SURFACE_KEY,
})
);
const wrapAgentSessionSplitPane = (panel: React.ReactNode) =>
wrapAux(panel, "agent-session-thread-panel", {
key: AGENT_SESSION_SURFACE_KEY,
});
const threadHeaderLeading = useSplitAuxiliaryPane ? (
<ThreadViewModeToggle onChange={changeThreadViewMode} />
) : undefined;
@@ -557,11 +543,6 @@ export const ChannelPane = React.memo(function ChannelPane({
isSinglePanelView,
useSplitAuxiliaryPane,
});
const agentSessionLayoutProps = getAgentSessionPanelPresentation({
isCoverDrawer: useAgentActivityDrawer,
isSinglePanelView,
useSplitAuxiliaryPane,
});
const timelineReplyHandler =
activeChannel?.archivedAt || isHuddleTranscript ? undefined : onOpenThread;
return (
@@ -910,42 +891,22 @@ export const ChannelPane = React.memo(function ChannelPane({
) : auxiliarySurface === "agent-session" &&
activeChannel &&
selectedAgent ? (
(() => {
// When the panel was opened from a different channel than the
// currently active one, re-scope it to the active channel so
// that both the content/header AND channel-backed actions (e.g.
// Stop current turn) operate on the same channel object.
const effectiveAgentSessionChannelId =
openAgentSessionChannelId &&
activeChannel.id !== openAgentSessionChannelId
? activeChannelId
: openAgentSessionChannelId;
const panel = (
<AgentSessionThreadPanel
agent={selectedAgent}
canInterruptTurn={selectedAgent.canInterruptTurn}
channel={
effectiveAgentSessionChannelId
? effectiveAgentSessionChannelId === activeChannel.id
? activeChannel
: null
: agentSessionSelection.isAgentInActivityList({
activityAgents,
selectedAgent,
})
? activeChannel
: null
}
channelId={effectiveAgentSessionChannelId}
{...agentSessionLayoutProps}
profiles={profiles}
onBack={onBackFromAgentSession}
onClose={onCloseAgentSession}
widthPx={threadPanelWidthPx}
/>
);
return wrapAgentSessionPanel(panel);
})()
<ChannelAgentSessionSurface
activeChannel={activeChannel}
activeChannelId={activeChannelId}
activityAgents={activityAgents}
agent={selectedAgent}
key={AGENT_SESSION_SURFACE_KEY}
isCoverDrawer={useAgentActivityDrawer}
isSinglePanelView={isSinglePanelView}
useSplitAuxiliaryPane={useSplitAuxiliaryPane}
onBack={onBackFromAgentSession}
onClose={onCloseAgentSession}
openAgentSessionChannelId={openAgentSessionChannelId}
profiles={profiles}
widthPx={threadPanelWidthPx}
wrapSplitPane={wrapAgentSessionSplitPane}
/>
) : auxiliarySurface === "profile" && profilePanelPubkey ? (
(() => {
const panel = (