fix(desktop): shared relay agents are un-mentionable/un-addable — let directory eligibility run#2605
Conversation
d7823de to
c455107
Compare
The composer's addCandidate dropped every agent-flagged identity not in the LOCAL managed-agents list before shouldHideAgentFromMentions ran, so the relay-directory eligibility path (kind:10100 RelayAgents with respond_to anyone/allowlist and a shared channel) was dead code for agents owned by other members. The members sidebar applied the same managed-list-only gate to add-member search. - useMentions: remove the pre-emptive gate; shouldHideAgentFromMentions is the single authority (it already shows invocable agents, hides non-member non-invocable ones, and applies the member/directory rules). - MembersSidebar: gate add-candidates on managed agents plus relay agents that would respond to the current user, via the new relayAgentIsInvocableByUser helper. Channel overlap is deliberately not required there - adding the agent is what creates the overlap. - relayAgentIsSharedWithUser now delegates its allowlist branch to the new helper; behavior unchanged. Closes block#2603 Signed-off-by: Lee Salminen <leesalminen@gmail.com>
c455107 to
0f1cc3a
Compare
|
Confirming the root cause from another angle in case it's useful for the review. Repro (mobile↔desktop parity): an externally-attested agent — one that joined a community via a NIP-OA owner One sanity check for the review: #2149's stated intent was narrower than "managed-only" — de-duping owner-less stale p-tag copies of a persona I already manage (e.g. Bumble). Removing the gate entirely also lets owner-less member duplicates back in. If preserving that dedupe matters, a more surgical variant exempts only member + attested agents: if (candidate.isAgent !== true) return true;
if (managedAgentPubkeys.has(normalizePubkey(candidate.pubkey))) return true;
return candidate.isMember === true && Boolean(candidate.ownerPubkey);
|
Closes #2603
Summary
A shared relay agent (kind:0 + NIP-OA auth tag, kind:10100 directory profile with
respond_to: anyone, channel member) responds fine when p-tagged, but nobody except its owning device can @-complete it or add it to channels:addCandidateinuseMentions.tsdrops every agent-flagged identity that isn't in the local managed-agents list beforeshouldHideAgentFromMentionsruns, making the directory-eligibility path (mentionableAgentPubkeys, and the "Invocable => always show" / member Option-B rules) unreachable for foreign agents.MembersSidebarapplies the same managed-list-only gate to add-member search.Changes
useMentions.ts: remove the pre-emptiveisAgentIdentityInManagedListgate.shouldHideAgentFromMentionsis the single authority — it already shows invocable agents (local managed ∪ relay-directory-eligible), hides non-member non-invocable ones, and applies the member/directory rules. Local managed agents are unaffected (they're seeded intomentionableAgentPubkeys), and other members'owner-onlyagents stay hidden (non-member + non-invocable, or member + directory-excluded).MembersSidebar.tsx: add-member candidates now pass when the agent is locally managed or relay-directory invocable by the current user (newrelayAgentIsInvocableByUser:respond_to: anyone, or an allowlist containing them). Channel overlap is deliberately not required here — adding the agent to the channel is what creates the overlap.agentAutocompleteEligibility.ts: newrelayAgentIsInvocableByUserhelper;relayAgentIsSharedWithUserdelegates its allowlist branch to it (behavior unchanged); doc comment onisAgentIdentityInManagedListclarifying the caller-supplied allow-set contract.Test plan
node --import ./test-loader.mjs --experimental-strip-types --testonagentAutocompleteEligibility.test.mjs: 22/22 (4 new: invocable-by-user modes, and a regression test that a directory-eligible member agent is shown without a local managed entry).biome checkandtsc --noEmitclean on touched files.respond_to: anyone): with this fix the agent appears in mention autocomplete and add-member search on a desktop that does not manage it.🤖 Generated with Claude Code