Skip to content

fix(discord): resolve deferred "thinking..." indicator after slash commands#3615

Open
Mibayy wants to merge 14 commits intoNousResearch:mainfrom
Mibayy:fix/discord-deferred-thinking-indicator
Open

fix(discord): resolve deferred "thinking..." indicator after slash commands#3615
Mibayy wants to merge 14 commits intoNousResearch:mainfrom
Mibayy:fix/discord-deferred-thinking-indicator

Conversation

@Mibayy
Copy link
Copy Markdown
Contributor

@Mibayy Mibayy commented Mar 28, 2026

Problem

Fixes #3595.

When a slash command (e.g. /usage, /insights) was issued, the gateway called interaction.response.defer() to show the Discord "hermes is thinking..." indicator, but then dispatched the actual response through handle_message() as a regular channel message — without ever resolving the deferred interaction. This left the placeholder orphaned, so both the "thinking..." bubble and the real response appeared simultaneously.

Root Cause

_run_simple_slash defers the interaction and dispatches the command, but the previous followup.send() call only ran when followup_msg was explicitly provided. For commands that don't pass a followup_msg (e.g. /usage, /insights), nothing cleaned up the deferred placeholder at all.

Fix

After handle_message() returns, the deferred interaction is always resolved:

  • With followup_msg: edit_original_response(content=followup_msg) replaces the placeholder with the confirmation text — one clean message instead of two.
  • Without followup_msg: delete_original_response() removes the placeholder so the "thinking..." indicator disappears.

Both paths are wrapped in try/except so a transient Discord API error during cleanup doesn't surface to the user.

# Before
if followup_msg:
    await interaction.followup.send(followup_msg, ephemeral=True)

# After
if followup_msg:
    await interaction.edit_original_response(content=followup_msg)
else:
    await interaction.delete_original_response()

Testing

Tested by issuing /usage, /insights, /reset, and /new in a Discord server with Hermes running. The "thinking..." indicator now disappears cleanly in all cases.

Mibayy added 14 commits March 28, 2026 23:21
Adds three tools for querying a self-hosted OpenViking server:
- viking_search: semantic search over memories, resources, and skills
  (auto/fast/deep modes)
- viking_read: read content at a viking:// URI with configurable detail
  levels (abstract / overview / read)
- viking_browse: explore the OpenViking filesystem layout (tree/list/stat)

All tools are gated behind check_fn that verifies the server is reachable,
so they are silently absent when OpenViking is not running — same pattern as
Honcho. The 'openviking' named toolset is also added to TOOLSETS and to
the shared tools list so gateway and CLI pick them up automatically.

Configure via:
  OPENVIKING_ENDPOINT  (default: http://127.0.0.1:1933)
  OPENVIKING_API_KEY   (optional, for secured deployments)

Closes NousResearch#3368
/model was fully implemented in hermes_cli/model_switch.py and
hermes_cli/main.py but was never registered in COMMAND_REGISTRY,
causing it to be absent from /help output and Telegram bot commands.

Fixes NousResearch#3371
…ic cache, detailed trace, opt-in checkpointing
- delegate_dag: deque.popleft() replaces queue.pop(0) -- O(1) vs O(n)
- delegate_checkpoint: single persistent conn + threading.Lock, WAL mode
- delegate_tool: _CRITIC_MAX_SUMMARY_CHARS constant, critic toolsets=[],
  debug log on skill miss, key.replace('_',' ').title() for unknown keys,
  blackboard comment
- openviking_tool: try/except on r.json() in search and read paths
- Remove docs/plans/subagent-v2-*.md planning artifacts, gitignore them
…mmand

When a slash command was handled, the gateway called interaction.response.defer()
to show the 'thinking...' indicator, but then dispatched the response as a new
message via handle_message() without ever resolving the deferred interaction.
This left the 'hermes is thinking...' placeholder orphaned alongside the real
response.

Fix: after handle_message() returns, always resolve the deferred interaction:
- If followup_msg is set, edit_original_response() replaces the placeholder
  with the confirmation text instead of sending a separate followup message.
- Otherwise, delete_original_response() removes the placeholder cleanly.

Both paths are wrapped in a try/except so a Discord API hiccup during cleanup
does not surface as an error to the user.

Fixes NousResearch#3595
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.

[Bug]: Discord gateway: "thinking..." deferred response indicator persists after final message is sent

1 participant