Skip to content

feat: Discord guild channels, slash commands, and agent handoff#141

Open
0x177630b6 wants to merge 6 commits intoTinyAGI:mainfrom
0x177630b6:feat/discord-channel-support
Open

feat: Discord guild channels, slash commands, and agent handoff#141
0x177630b6 wants to merge 6 commits intoTinyAGI:mainfrom
0x177630b6:feat/discord-channel-support

Conversation

@0x177630b6
Copy link

Summary

  • Discord guild channel support — Bind server channels to specific agents via guild_channels config. Messages in bound channels auto-route to the configured agent without requiring @ prefix. Bot responds to @mentions and designated channels while ignoring other guild messages.
  • Discord slash commands/agent, /team, /reset registered as native guild slash commands with autocomplete. Text-based !agent/!team/!reset fallback removed. Slash commands auto-register on bot startup and when joining new guilds (GuildCreate handler).
  • Agent-to-agent handoff — Non-team agents can hand off work via @agent_id prefix in responses. Handoffs are re-enqueued with depth tracking (max 5 hops) to prevent infinite loops. Both agent IDs and names are supported (names are rewritten to IDs).
  • Agent response signatures — Responses include — AgentName suffix on Discord, controlled by channels.discord.sign_responses (defaults to true).
  • Cached settings readergetCachedSettings() with mtime-based invalidation replaces 5 separate fs.readFileSync + JSON.parse calls in the Discord client.
  • Shared helpersinteractionReplySplit() for split reply/followUp pattern, resetAgents() for reset logic, registerGuildCommands() for slash command registration.
  • Fix nested Claude Code sessions — Strips CLAUDECODE env var when spawning agent subprocesses to prevent session conflicts.
  • Conversation senderId passthroughsenderId now flows through to completeConversation() so team responses route back to the correct guild channel.

Files changed

File Changes
src/channels/discord-client.ts Guild channels, slash commands, cached settings, agent signatures, remove text commands
src/queue-processor.ts Agent handoff via parseResponseHandoff, remove inline [signed:] suffix
src/lib/routing.ts New parseResponseHandoff(), fix name-to-ID rewrite on handoff
src/lib/db.ts handoff_depth column and field
src/lib/types.ts guild_channels, sign_responses, senderId on Conversation
src/lib/conversation.ts Pass senderId through to enqueueResponse
src/lib/invoke.ts Strip CLAUDECODE env from child processes
README.md Document slash commands, guild channels, handoff, sign_responses

Test plan

  • npm run build:main compiles clean
  • ./tinyclaw.sh restart — check logs for "Registered 3 slash commands for guild"
  • In Discord: type / and verify agent, team, reset appear in autocomplete
  • /agent — lists all agents (handles >2000 char responses via message splitting)
  • /team — lists all teams
  • /reset coder — resets agent, verify autocomplete suggests agent IDs
  • Send message in a bound guild channel — verify it routes to the configured default agent
  • Verify — AgentName signature appears on responses
  • Set "sign_responses": false in channels.discord — verify signature disappears
  • Verify agent-to-agent handoff works (agent responds with @other_agent message)

🤖 Generated with Claude Code

Ubuntu and others added 6 commits February 25, 2026 04:26
…ssions

Add guild/server message handling to Discord client with @mention and
designated channel support, role mention stripping, and default agent
routing. Fix child Claude Code processes failing due to inherited
CLAUDECODE env var. Pass senderId through conversation pipeline so
responses route back to the correct channel.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When an agent responds with @agent_id prefix, the system intercepts the
response, delivers it to the user for full transparency, and re-enqueues
it as a new message for the target agent — preserving original channel
and sender context.

- Add parseResponseHandoff() to routing.ts for detecting @agent mentions
- Add handoff_depth column to messages table with idempotent migration
- Intercept responses in queue-processor with depth-limited re-enqueue
- Loop prevention via MAX_HANDOFF_DEPTH (5) and self-handoff rejection
- System-level [signed: @agentName] suffix on all agent responses

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t signatures

- Register /agent, /team, /reset as guild slash commands with autocomplete
- Remove text-based !agent/!team/!reset fallback commands
- Add cached getCachedSettings() (mtime-based) to eliminate redundant file reads
- Extract interactionReplySplit() and resetAgents() shared helpers
- Add GuildCreate handler to register commands when bot joins new guilds
- Move agent signature from inline [signed:] text to per-channel "— AgentName" suffix
- Fix parseResponseHandoff to rewrite @name to @id on name-matched handoffs
- Add sign_responses setting type

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tures

- Respect sign_responses setting in Discord client (defaults to true)
- Remove unused signed response logic from queue-processor
- Update README: slash commands, guild channels, agent handoff, sign_responses

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Discord-only setting belongs in the discord channel config, not at root level.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

1 participant