Skip to content

fix(desktop): shared relay agents are un-mentionable/un-addable — let directory eligibility run#2605

Open
leesalminen wants to merge 1 commit into
block:mainfrom
leesalminen:fix/shared-relay-agents-mentionable
Open

fix(desktop): shared relay agents are un-mentionable/un-addable — let directory eligibility run#2605
leesalminen wants to merge 1 commit into
block:mainfrom
leesalminen:fix/shared-relay-agents-mentionable

Conversation

@leesalminen

Copy link
Copy Markdown
Contributor

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: addCandidate in useMentions.ts drops every agent-flagged identity that isn't in the local managed-agents list before shouldHideAgentFromMentions runs, making the directory-eligibility path (mentionableAgentPubkeys, and the "Invocable => always show" / member Option-B rules) unreachable for foreign agents. MembersSidebar applies the same managed-list-only gate to add-member search.

Changes

  • useMentions.ts: remove the pre-emptive isAgentIdentityInManagedList gate. shouldHideAgentFromMentions is 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 into mentionableAgentPubkeys), and other members' owner-only agents 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 (new relayAgentIsInvocableByUser: 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: new relayAgentIsInvocableByUser helper; relayAgentIsSharedWithUser delegates its allowlist branch to it (behavior unchanged); doc comment on isAgentIdentityInManagedList clarifying the caller-supplied allow-set contract.

Test plan

  • node --import ./test-loader.mjs --experimental-strip-types --test on agentAutocompleteEligibility.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 check and tsc --noEmit clean on touched files.
  • Manually verified against a self-hosted multi-tenant relay running a headless shared agent (buzz-acp + kind:10100, 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

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>
@leesalminen
leesalminen force-pushed the fix/shared-relay-agents-mentionable branch from c455107 to 0f1cc3a Compare July 25, 2026 15:19
@jonathanleiva15

Copy link
Copy Markdown

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 auth tag (ViaOwner relay membership) and is a channel member — is mentionable in the mobile client but not in desktop, on the same account/relay. Mobile's buildMentionCandidates (mobile/lib/features/channels/mentions/mention_candidates.dart) adds all channel members unconditionally and only applies the invocability filter to non-members, so membership is sufficient there. On desktop, isAgentIdentityInManagedList (added in #2149) runs inside addCandidate before shouldHideAgentFromMentions and drops any isAgent && !managedAgentPubkeys.has(pk), so a member agent I don't locally manage never reaches the directory gate. Removing that pre-gate (this PR) restores the mobile semantics 👍

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);

ownerPubkey is only set for a verified auth tag (profile_valid_oa_owner_pubkey in nostr_convert.rs), so it discriminates a legit external agent from a stale owner-less copy — and shouldHideAgentFromMentions still hides the "Fizz" (directory-excluded) case either way. Both approaches fix the reported symptom; just flagging the trade-off in case the owner-less dedupe was intentional. Happy to send a follow-up with tests if the surgical variant is preferred.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Desktop: shared relay agents owned by other members are un-mentionable and un-addable (managed-list gate precedes directory eligibility)

2 participants