diff --git a/desktop/src/features/agents/lib/agentAutocompleteEligibility.test.mjs b/desktop/src/features/agents/lib/agentAutocompleteEligibility.test.mjs index 4e02b7bd68..aa8241af6a 100644 --- a/desktop/src/features/agents/lib/agentAutocompleteEligibility.test.mjs +++ b/desktop/src/features/agents/lib/agentAutocompleteEligibility.test.mjs @@ -227,6 +227,26 @@ test("shouldHideAgentFromMentions: shows member agents with unknown invocability ); }); +test("shouldHideAgentFromMentions: #4187 shows a channel-member agent managed by another Desktop instance", () => { + // Regression for #4187: a managed agent running on another Desktop instance + // appears here as a channel member (isAgent via role "bot") that is neither + // in this client's managed-agent list nor in the relay directory + // (mentionableAgentPubkeys/directoryAgentPubkeys both empty). It MUST remain + // visible in the mention picker. The mention path (useMentions) must rely on + // this policy alone and not additionally pre-filter with + // isAgentIdentityInManagedList, which would drop it. + assert.equal( + shouldHideAgentFromMentions({ + isAgent: true, + isMember: true, + pubkey: PUB_A, + mentionableAgentPubkeys: new Set(), + directoryAgentPubkeys: new Set(), + }), + false, + ); +}); + test("shouldHideAgentFromMentions: normalizes the pubkey before lookup", () => { const mixedCase = "Ab".repeat(32); const normalized = mixedCase.toLowerCase(); diff --git a/desktop/src/features/messages/lib/useMentions.ts b/desktop/src/features/messages/lib/useMentions.ts index 0c73b75339..abaaf0e211 100644 --- a/desktop/src/features/messages/lib/useMentions.ts +++ b/desktop/src/features/messages/lib/useMentions.ts @@ -16,7 +16,6 @@ import { coalesceAutocompleteCandidatesByKey, getMentionableAgentPubkeys, getSharedChannelIds, - isAgentIdentityInManagedList, shouldHideAgentFromMentions, } from "@/features/agents/lib/agentAutocompleteEligibility"; import { @@ -246,9 +245,16 @@ export function useMentions( if (isArchivedDiscovery(pubkey)) { return; } - if (!isAgentIdentityInManagedList(candidate, managedAgentPubkeys)) { - return; - } + // Agent visibility in the mention picker is governed solely by + // `shouldHideAgentFromMentions` (the "Option B" member/directory policy + // below). We deliberately do NOT pre-filter with + // `isAgentIdentityInManagedList` here: that gate keeps only *locally* + // managed agents, which drops channel-member agents managed by another + // Desktop instance before the member/directory policy can show them — + // the root cause of #4187 (cross-desktop managed agents missing from the + // `@mention` autocomplete). `isAgentIdentityInManagedList` still belongs + // in the "add member" search (MembersSidebar), where you may only add + // agents you manage; it does not belong on the mention path. if ( shouldHideAgentFromMentions({ isAgent: candidate.isAgent === true, @@ -420,7 +426,6 @@ export function useMentions( managedAgentNamesByPubkey, managedAgentPersonaIds, managedAgentPersonaIdsByPubkey, - managedAgentPubkeys, managedAgentsQuery.data, memberPubkeys, members,