Skip to content

fix: prevent agent proliferation when adding bots to channels#621

Merged
tellaho merged 4 commits into
mainfrom
tho/agent-reuse-guard
May 20, 2026
Merged

fix: prevent agent proliferation when adding bots to channels#621
tellaho merged 4 commits into
mainfrom
tho/agent-reuse-guard

Conversation

@tellaho
Copy link
Copy Markdown
Collaborator

@tellaho tellaho commented May 19, 2026

Category: improvement
User Impact: Adding an agent to a channel now reuses an existing instance by default instead of spawning a duplicate, reducing agent sprawl from dozens of redundant keypairs down to one per persona.

Problem: The "+" button in channel headers spawned a brand-new managed agent (new keypair) every time — even when that persona already had a running agent. This led to 79 agent instances and 89 unique bot pubkeys across 26 channels.

Solution: Strengthen the reuse logic so existing agents are attached to new channels by default. A guardrail UI (select dropdown) lets users explicitly opt into creating a fresh instance when isolation is needed.


File changes

desktop/src/features/agents/agentReuse.ts
New file. Extracted reuse helper functions: findReusablePersonaAgent (existing logic, moved here), findReusableGenericAgent (new — matches on command + blank prompt), and findReusableAgent (unified entry point for the UI hook).

desktop/src/features/agents/channelAgents.ts
Refactored to import reuse helpers from agentReuse.ts. Added forceNewInstance gate to both persona and generic reuse paths so the UI escape hatch works. Added the new generic agent reuse block (command match + empty prompt guard).

desktop/src/features/agents/hooks.ts
Re-exports findReusableAgent from agentReuse.ts so the detection hook can import it cleanly.

desktop/src/features/channels/ui/AddChannelBotDialog.tsx
Integrates the reuse detection hook and renders the AddChannelBotReuseGuard component when a reusable agent is found. Passes forceNewInstance into the mutation inputs.

desktop/src/features/channels/ui/AddChannelBotReuseGuard.tsx
New component. Select dropdown (label + select + helper text pattern, matching RespondToField) that defaults to "Reuse existing agent" with opt-out to "Create new instance."

desktop/src/features/channels/ui/useReusableAgentDetection.ts
New hook. Detects whether a reusable managed agent exists for the current dialog selection (single persona or blank generic) so the UI can show the guardrail before submission.


Reproduction Steps

  1. Run the desktop app, ensure you have at least one persona configured (e.g., Goose).
  2. Add that persona to a channel via the "+" button — it creates a new agent as usual.
  3. Navigate to a different channel and click "+" again, select the same persona.
  4. Observe the new "Agent instance" dropdown appears, defaulting to "Reuse existing agent."
  5. Submit — the existing agent is attached to the new channel without creating a duplicate.
  6. To verify the escape hatch: repeat step 3, switch the dropdown to "Create new instance," and confirm a new agent with a fresh keypair is created.

@tellaho tellaho force-pushed the tho/agent-reuse-guard branch from 7c6f331 to bf26ca6 Compare May 20, 2026 00:01
@tellaho tellaho marked this pull request as ready for review May 20, 2026 01:50
@tellaho tellaho requested a review from wesbillman as a code owner May 20, 2026 01:50
tellaho added 4 commits May 20, 2026 11:55
…l UI

- Extract reuse helpers into agentReuse.ts (commandsMatch, pickPreferred,
  findReusablePersonaAgent, findReusableGenericAgent, findReusableAgent)
- Add generic agent reuse: when no persona and no custom prompt, reuse
  existing agent with matching command instead of spawning a new keypair
- Add forceNewInstance flag to CreateChannelManagedAgentInput so users
  can explicitly opt into creating a fresh instance
- Guard both persona and generic reuse paths with forceNewInstance check
- Add useReusableAgentDetection hook for UI-side reuse detection
- Add AddChannelBotReuseGuard component: radio choice defaulting to
  reuse, with opt-out for 'Create new instance'
- Wire guardrail into AddChannelBotDialog — shows when reuse would fire
  for single-agent selections (1 persona or generic with blank prompt)
Replace bordered card with radio buttons → label + select dropdown +
helper text. Same visual plane as 'Who can talk to this agent' field.
Covers commandsMatch, parseTimestamp, pickPreferredManagedAgent,
findReusablePersonaAgent, findReusableGenericAgent, and findReusableAgent.

38 test cases covering edge cases:
- Path normalization and claude command aliasing
- Whitespace-only vs empty vs undefined systemPrompt
- Running vs stopped agent preference
- Null/undefined timestamp handling
- Channel member exclusion logic
@tellaho tellaho force-pushed the tho/agent-reuse-guard branch from bf26ca6 to 0024a61 Compare May 20, 2026 18:57
@tellaho tellaho changed the title prevent agent proliferation when adding bots to channels fix: prevent agent proliferation when adding bots to channels May 20, 2026
@tellaho tellaho merged commit af08b0f into main May 20, 2026
15 checks passed
@tellaho tellaho deleted the tho/agent-reuse-guard branch May 20, 2026 19:08
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.

2 participants