Skip to content

feat(huddle): offer the team's server-side agents in the huddle picker - #30

Merged
mattbalza merged 2 commits into
mainfrom
feat/huddle-remote-agents
Aug 7, 2026
Merged

feat(huddle): offer the team's server-side agents in the huddle picker#30
mattbalza merged 2 commits into
mainfrom
feat/huddle-remote-agents

Conversation

@mattbalza

Copy link
Copy Markdown
Owner

What

Add-agent in a huddle listed only the agents this desktop runs itself. A huddle started from a channel where @erp, @codex, @claude and @seek answer every day could not have one of them in it — even though the backend has accepted a pubkey and sent the kind:9000 all along (huddle/agents.rs::add_agent_to_huddle). The gap was entirely in the picker, which populated from list_managed_agents only.

The picker now shows the union of managed agents and the relay directory, scoped exactly like a mention: an agent appears only if the viewer could have @mentioned it in the huddle's parent channel (getMentionableAgentPubkeys with eligibilityScope: { type: "channel", channelId }). Allowlists and owner-only agents stay where they were.

Nothing auto-joins. The picker is the only way in.

Shape

  • desktop/src/features/huddle/lib/huddleAgentCandidates.ts — new. huddleAllowsAgents(parentChannelType) and buildHuddleAgentCandidates(...). Managed agents win when an agent is in both sources; already-in-huddle pubkeys are dropped case-insensitively; with no parent channel id it returns managed only, because community scope would offer agents that cannot speak here.
  • AddAgentDialog.tsx — takes parentChannelId, unions the two sources, tags each entry data-agent-source="managed" | "remote" and badges remote ones Team.
  • Remote entries carry no lifecycle. Their process runs on the server under their own identity, so adding one is a membership event and nothing more: no start_managed_agent, no stop_managed_agent, no rollback aimed at a process this desktop does not own. The existing parent_error warning path is unchanged.
  • HuddleBar.tsx — a huddle whose parent is a DM offers no agents at all, the same rule DM threads already follow. HuddleState carries the parent's id but not its type, so the type is resolved from the channel list.

Test plan

  • node --import ./test-loader.mjs --experimental-strip-types --test "src/features/huddle/**/*.test.mjs"29 pass, 0 fail (9 new, covering the mention rule per channel type, per-viewer allowlists, dual-source dedupe, and the no-parent case).
  • npx playwright test --project=smoke tests/e2e/huddle-agents.spec.ts3 passed: a parent-scoped relay agent is offered as remote; one scoped to another channel is not; clicking a remote entry logs add_agent_to_huddle and neither start_managed_agent nor stop_managed_agent; a DM-parented huddle renders no Add-agent button.
  • tsc --noEmit and biome check clean.

Verified the pre-fix bundle renders only the managed agent with no data-agent-source — which is what these tests catch.

Add-agent listed only the agents this desktop runs itself, so a huddle
started from a channel where @erp, @codex, @claude and @Seek answer every
day could not have one of them in it — the backend has taken a pubkey and
sent a kind:9000 all along, and nothing on the client ever offered one.

The picker now shows the union of managed agents and the relay directory,
scoped exactly like a mention: an agent appears only if the user could have
@mentioned it in the huddle's parent channel, so allowlists and owner-only
agents stay where they were. Nothing joins on its own — the picker is the
only way in.

Remote entries carry no lifecycle. Their process runs on the server under
their own identity, so adding one is a membership event and nothing more:
no start, no stop, no rollback aimed at a process this desktop does not own.

A huddle whose parent is a DM offers no agents at all, the same rule DM
threads already follow. `HuddleState` carries the parent's id but not its
type, so the type is resolved from the channel list.
@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

The px-text ratchet refuses `text-[10px]`: a hard pixel size does not
scale with Cmd +/- zoom, so the badge stays 10px while everything around
it grows. `text-2xs` is the meta-text token the other badges already
use.
@mattbalza
mattbalza merged commit 3188b8d into main Aug 7, 2026
23 checks passed
@mattbalza
mattbalza deleted the feat/huddle-remote-agents branch August 7, 2026 16:33
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.

1 participant