Skip to content

fix: prevent Discord NO_REPLY bot loops (#29932) - #29942

Closed
zombi3butt wants to merge 7 commits into
NousResearch:mainfrom
zombi3butt:fix/discord-no-reply-bot-loops
Closed

fix: prevent Discord NO_REPLY bot loops (#29932)#29942
zombi3butt wants to merge 7 commits into
NousResearch:mainfrom
zombi3butt:fix/discord-no-reply-bot-loops

Conversation

@zombi3butt

Copy link
Copy Markdown

Three-layer fix for Discord bot-to-bot silence token handling:

  1. Entry filter (_handle_message): Drop Discord bot messages with content exactly "NO_REPLY" before they enter the agent loop. When DISCORD_ALLOW_BOTS=mentions, other bots' NO_REPLY must be ignored.
  2. Backfill exclusion (_fetch_channel_context): Exclude NO_REPLY sentinel messages from channel history backfill so they don't contaminate session context.
  3. Delivery suppression (send): Suppress literal NO_REPLY responses from being sent to Discord channels — it's a control/silence token, not user-facing content.

Fixes #29932

3ighty2O and others added 6 commits May 21, 2026 21:17
…me dict (issue NousResearch#29872)

When resolving named custom providers (custom:<name>), the returned
runtime dict previously collapsed provider to bare 'custom', losing
the specific sub-provider identity. This caused TUI display and
credential pool lookups to show only 'custom' instead of
'custom:bobapi-deepseek' etc.

Changes:
- _try_resolve_from_custom_pool: preserve sub-provider name in
  returned provider field as 'custom:<name>'
- _resolve_named_custom_runtime: non-pool return path uses
  'custom:<name>' for the provider field
- Bare 'custom' with explicit base_url remains unchanged

Updated tests to reflect new expected provider values.
When provider hooks silently strip the role="system" message (known with
some Ollama Cloud variants), re-inject from original input so SOUL.md is
never lost mid-flight. Adds defensive verification in _build_kwargs_from_profile.
…esearch#29920)

Two-layer fix for `HTTP 400: invalid message content type: map[string]interface{}`.

1. `_tool_result_content_for_active_model` in run_agent.py — serializes
   non-string, non-list results (Python dicts/lists from MCP tools or memory
   helpers) as JSON before appending to messages. Falls back to repr() on
   serialization failure.

2. `sanitize_api_messages` in agent_runtime_helpers.py — coerces tool role
   `content` to JSON string as a safety-net before every API call. Catches
   any tool results that bypass the first layer (e.g. from session restore
   or manual message manipulation).

Fixes the 'model provider failed after retries' loop caused by a single bad
tool result poisoning the entire message history.
Three-layer fix for Discord bot-to-bot silence token handling:

1. Entry filter (_handle_message): Drop Discord bot messages with content
   exactly "NO_REPLY" before they enter the agent loop. When
   DISCORD_ALLOW_BOTS=mentions, other bots' NO_REPLY must be ignored.

2. Backfill exclusion (_fetch_channel_context): Exclude NO_REPLY sentinel
   messages from channel history backfill so they don't contaminate session
   context.

3. Delivery suppression (send): Suppress literal NO_REPLY responses from
   being sent to Discord channels — it's a control/silence token, not
   user-facing content.

Fixes noisy bot-to-bot loops caused by agent silence being surfaced as
empty-response retries.
@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery platform/discord Discord bot adapter P2 Medium — degraded but workaround exists labels May 21, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related to #29932 (same Discord NO_REPLY fix by different author). Note: this PR bundles unrelated changes from #29937 (JSON-serialize tool results) and #29935 (ollama-cloud system-message guard). Please split into separate PRs.

…onversation (issue NousResearch#29926)

When auto-compression rotates the session mid-run, result["messages"]
contains the inflated post-turn list (compressed baseline + this turn's
growth). The CLI was overwriting conversation_history with this inflated
list, causing the next turn to start from 130K+ tokens instead of the
compressed ~24K baseline — wasting VRAM and API time.

Fix: detect session rotation via _cli_last_run_old_session_id (captured
before run_conversation in the agent thread) and use agent._session_messages
instead of result["messages"] when rotation occurred. Falls back to
result["messages"] for normal (non-rotated) runs.

Mirrors the gateway path fix in PR NousResearch#29505.
@zombi3butt

Copy link
Copy Markdown
Author

Closing per alt-glitch review: this PR bundles unrelated changes from #29937 (JSON-serialize tool results), #29935 (ollama-cloud system-message guard), plus test additions and other files. The Discord NO_REPLY fix (#29932) should be submitted as its own focused PR. Bundling unrelated changes makes review and merge impossible.

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

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/discord Discord bot adapter type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants