mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
Defer task opens until agents resolve
This commit is contained in:
@@ -64,6 +64,7 @@ import { normalizePubkey } from "@/shared/lib/pubkey";
|
||||
export const ChannelPane = React.memo(function ChannelPane({
|
||||
activeChannel,
|
||||
agentConversationMarkers,
|
||||
agentLookupReady = true,
|
||||
agentPubkeys,
|
||||
agentPubkeysPending = false,
|
||||
agentSessionAgents,
|
||||
@@ -155,6 +156,12 @@ export const ChannelPane = React.memo(function ChannelPane({
|
||||
const [taskFocusMessageId, setTaskFocusMessageId] = React.useState<
|
||||
string | null
|
||||
>(null);
|
||||
const [pendingAgentConversationOpen, setPendingAgentConversationOpen] =
|
||||
React.useState<{
|
||||
channelId: string;
|
||||
messageId: string;
|
||||
publishMarker?: boolean;
|
||||
} | null>(null);
|
||||
const previousTaskFocusChannelIdRef = React.useRef<string | null>(null);
|
||||
const completedWelcomeBannerChannelIdsRef = React.useRef(new Set<string>());
|
||||
const welcomeComposerDismissTimerRef = React.useRef<number | null>(null);
|
||||
@@ -316,6 +323,19 @@ export const ChannelPane = React.memo(function ChannelPane({
|
||||
}, [activityAgents, agentPubkeys, agentSessionAgents, profiles]);
|
||||
const resolveTaskAgentForMessage = React.useCallback(
|
||||
(message: TimelineMessage) => {
|
||||
const markerAgent = activeAgentConversationMarkers?.find(
|
||||
(marker) =>
|
||||
marker.channelId === activeChannelId &&
|
||||
marker.agentReplyId === message.id &&
|
||||
marker.agentPubkey,
|
||||
);
|
||||
if (markerAgent) {
|
||||
return {
|
||||
name: markerAgent.agentName || markerAgent.agentPubkey,
|
||||
pubkey: markerAgent.agentPubkey,
|
||||
};
|
||||
}
|
||||
|
||||
if (message.pubkey) {
|
||||
const directAgent = knownAgentByPubkey.get(
|
||||
normalizePubkey(message.pubkey),
|
||||
@@ -326,6 +346,15 @@ export const ChannelPane = React.memo(function ChannelPane({
|
||||
pubkey: directAgent.pubkey,
|
||||
};
|
||||
}
|
||||
if (message.role === "bot") {
|
||||
return {
|
||||
name:
|
||||
message.author?.trim() ||
|
||||
message.personaDisplayName?.trim() ||
|
||||
message.pubkey,
|
||||
pubkey: message.pubkey,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
for (const pubkey of collectMessageMentionPubkeys([message])) {
|
||||
@@ -337,7 +366,7 @@ export const ChannelPane = React.memo(function ChannelPane({
|
||||
|
||||
return null;
|
||||
},
|
||||
[knownAgentByPubkey],
|
||||
[activeAgentConversationMarkers, activeChannelId, knownAgentByPubkey],
|
||||
);
|
||||
const completeWelcomeComposerBanner = React.useCallback(() => {
|
||||
if (!activeChannelId || !isActiveWelcomeChannel) {
|
||||
@@ -395,8 +424,12 @@ export const ChannelPane = React.memo(function ChannelPane({
|
||||
},
|
||||
[onOpenAgentSession],
|
||||
);
|
||||
const handleOpenAgentConversation = React.useCallback(
|
||||
(message: TimelineMessage, options?: { publishMarker?: boolean }) => {
|
||||
const openResolvedAgentConversation = React.useCallback(
|
||||
(
|
||||
message: TimelineMessage,
|
||||
taskAgent: { name: string; pubkey: string } | null,
|
||||
options?: { publishMarker?: boolean },
|
||||
) => {
|
||||
if (
|
||||
!enableAgentConversations ||
|
||||
!activeChannel ||
|
||||
@@ -409,7 +442,6 @@ export const ChannelPane = React.memo(function ChannelPane({
|
||||
return;
|
||||
}
|
||||
|
||||
const taskAgent = resolveTaskAgentForMessage(message);
|
||||
const rootId = message.rootId ?? message.parentId ?? message.id;
|
||||
const contextMessages = messages.filter(
|
||||
(candidate) =>
|
||||
@@ -437,14 +469,79 @@ export const ChannelPane = React.memo(function ChannelPane({
|
||||
options,
|
||||
);
|
||||
},
|
||||
[activeChannel, enableAgentConversations, messages, openAgentConversation],
|
||||
);
|
||||
const handleOpenAgentConversation = React.useCallback(
|
||||
(message: TimelineMessage, options?: { publishMarker?: boolean }) => {
|
||||
if (
|
||||
!enableAgentConversations ||
|
||||
!activeChannel ||
|
||||
message.pending ||
|
||||
!canOpenAgentConversationInChannel({
|
||||
channel: activeChannel,
|
||||
publishMarker: options?.publishMarker,
|
||||
})
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const taskAgent = resolveTaskAgentForMessage(message);
|
||||
if (!taskAgent && !agentLookupReady) {
|
||||
setPendingAgentConversationOpen({
|
||||
channelId: activeChannel.id,
|
||||
messageId: message.id,
|
||||
publishMarker: options?.publishMarker,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
openResolvedAgentConversation(message, taskAgent, options);
|
||||
},
|
||||
[
|
||||
activeChannel,
|
||||
agentLookupReady,
|
||||
enableAgentConversations,
|
||||
messages,
|
||||
openAgentConversation,
|
||||
openResolvedAgentConversation,
|
||||
resolveTaskAgentForMessage,
|
||||
],
|
||||
);
|
||||
React.useEffect(() => {
|
||||
if (!pendingAgentConversationOpen) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!activeChannel ||
|
||||
activeChannel.id !== pendingAgentConversationOpen.channelId
|
||||
) {
|
||||
setPendingAgentConversationOpen(null);
|
||||
return;
|
||||
}
|
||||
if (!agentLookupReady) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pendingMessage = messages.find(
|
||||
(message) => message.id === pendingAgentConversationOpen.messageId,
|
||||
);
|
||||
if (!pendingMessage || pendingMessage.pending) {
|
||||
setPendingAgentConversationOpen(null);
|
||||
return;
|
||||
}
|
||||
|
||||
setPendingAgentConversationOpen(null);
|
||||
openResolvedAgentConversation(
|
||||
pendingMessage,
|
||||
resolveTaskAgentForMessage(pendingMessage),
|
||||
{ publishMarker: pendingAgentConversationOpen.publishMarker },
|
||||
);
|
||||
}, [
|
||||
activeChannel,
|
||||
agentLookupReady,
|
||||
messages,
|
||||
openResolvedAgentConversation,
|
||||
pendingAgentConversationOpen,
|
||||
resolveTaskAgentForMessage,
|
||||
]);
|
||||
const handleGoToTaskMessage = React.useCallback(
|
||||
(
|
||||
marker: AgentConversationMarker,
|
||||
|
||||
@@ -16,6 +16,7 @@ import type { Channel } from "@/shared/api/types";
|
||||
export type ChannelPaneProps = {
|
||||
activeChannel: Channel | null;
|
||||
agentConversationMarkers?: readonly AgentConversationMarker[];
|
||||
agentLookupReady?: boolean;
|
||||
activityAgents?: BotActivityAgent[];
|
||||
agentPubkeys?: ReadonlySet<string>;
|
||||
agentPubkeysPending?: boolean;
|
||||
|
||||
@@ -344,6 +344,7 @@ export function ChannelScreen({
|
||||
const agentLookupReady =
|
||||
!channelMembersQuery.isLoading &&
|
||||
!managedAgentsQuery.isLoading &&
|
||||
!messageProfilesQuery.isLoading &&
|
||||
!relayAgentsQuery.isLoading;
|
||||
const agentPubkeys = React.useMemo(() => {
|
||||
const pubkeys = new Set<string>();
|
||||
@@ -986,6 +987,7 @@ export function ChannelScreen({
|
||||
activeChannel={activeChannel}
|
||||
activityAgents={channelAgentSessionAgents}
|
||||
agentConversationMarkers={agentConversationMarkers}
|
||||
agentLookupReady={agentLookupReady}
|
||||
agentPubkeys={routingAgentPubkeys}
|
||||
agentPubkeysPending={agentPubkeysPending}
|
||||
agentSessionAgents={agentSessionAgents}
|
||||
|
||||
Reference in New Issue
Block a user