Skip to content

fix(clarify): show decision context and compact Discord choices - #64480

Closed
RunLittleTurtle wants to merge 2 commits into
NousResearch:mainfrom
RunLittleTurtle:fix/clarify-context-rich
Closed

fix(clarify): show decision context and compact Discord choices#64480
RunLittleTurtle wants to merge 2 commits into
NousResearch:mainfrom
RunLittleTurtle:fix/clarify-context-rich

Conversation

@RunLittleTurtle

Copy link
Copy Markdown

Summary

  • require an explicit, self-contained context for model-generated clarify prompts
  • render that context above the focused question on every platform callback
  • keep the full canonical choices visible as a numbered list in Discord message content and embeds
  • label Discord buttons with the matching number and a compact action label (1 · Approve) instead of numbers alone or clipped explanations
  • preserve the full original choice as the callback value after a click
  • use secondary button styling for equal-significance choices, following Discord guidance
  • document the native prompt contract and add regression coverage across the tool, executor, Discord, Telegram, and gateway

Why

Discord mobile clients truncate long button labels well before the API's 80-character limit. More importantly, a clarify card could previously ask the user to approve “the diff shown” or “this proposal” even when that context was only present in the agent's internal reasoning. The user then saw clipped controls without enough visible information to make an informed choice.

The new contract separates the two responsibilities:

  • message body: complete context plus full numbered options
  • controls: the same number plus a short action label

Choices use the format Short label — full explanation, so the relationship stays obvious while the canonical value remains unchanged.

Community credit

This branch includes and preserves the author commit from #62291, which introduced the full numbered choice list and numeric controls after repeated real-user reports. This PR extends that work with explicit decision context and meaningful compact button labels.

Related reports and prior work: #37134, #41353, #60245, #62291.

Compatibility

  • context is appended to the Python helper signature, so existing positional callback callers remain compatible.
  • model-facing tool calls require context in the schema.
  • multiple-choice calls that bypass the schema fail closed when context is missing.
  • open-ended direct Python callers remain backward-compatible.
  • Telegram's existing full-choice rendering remains unchanged and covered by tests.

Verification

101 tests passed, 0 failed

Command:

scripts/run_tests.sh \
  tests/tools/test_clarify_tool.py \
  tests/tools/test_clarify_gateway.py \
  tests/gateway/test_discord_clarify_buttons.py \
  tests/gateway/test_discord_prompt_content_siblings.py \
  tests/gateway/test_telegram_clarify_buttons.py \
  tests/gateway/test_clarify_active_session_bypass.py \
  tests/run_agent/test_tool_call_guardrail_runtime.py -q

Additional checks:

  • ruff check on all changed Python files: pass
  • python -m py_compile on production modules: pass
  • git diff --check: pass

Hermes Coder and others added 2 commits July 14, 2026 10:40
Discord clarify buttons put the (truncated) choice text directly on
the button label, relying on Discord's 80-char label cap plus a
word-boundary truncation algorithm. In practice this is still
unreadable: Discord mobile clients wrap/cut button text well before
80 chars (often <40 visible), so any truncation strategy on the
label itself still garbles longer choices regardless of how the cut
point is chosen.

PR #54969 (merged as 87be36c) already fixed a related but
different bug in this same truncation path -- code-point slicing
instead of UTF-16 unit slicing, which could corrupt emoji-heavy
choice text at the cut boundary. That fix made the truncation
correct; this one removes the need for truncation at all.

Telegram and WhatsApp adapters already avoid this class of bug
entirely: button labels are just a short index, and the full choice
text is mirrored in the message body where there's no meaningful
length cap. This brings Discord's send_clarify() in line with that
same pattern:

- ClarifyChoiceView button labels are now just the option number
  ("1", "2", ...) instead of "1. <truncated text>". Removed the
  now-dead word/soft-boundary truncation logic for this path.
- send_clarify() renders the full, untruncated choice text as a
  numbered list in the embed's "Choices" field (1024-char cap,
  truncated only if genuinely absurd) and mirrors it again in the
  plain-text message content, matching the existing embeds-may-be-
  invisible-on-some-clients precaution already used elsewhere in
  this adapter.

Related: #36186 (different bug in the same file -- clarify text
disappearing when Discord hides embed bodies entirely, not button
label truncation).

Review fixes (per hermes-sweeper automated review on PR #62291):
- The embed field truncation only capped the option-list portion at
  1024 chars, then appended a ~65-char instruction suffix afterward --
  the combined value could reach ~1089 chars, over Discord's real
  1024-char embed-field limit, causing send_clarify() to fail on
  exactly the long-choice-list case this fix exists to handle. Now
  reserves suffix length before truncating so the combined field
  value never exceeds the cap. Added a boundary regression test with
  24 long choices asserting the rendered field stays <= 1024 chars
  and the suffix is never dropped.
- The plain-text message-content mirror now explicitly uses the
  *untruncated* option list (Discord's 2000-char content cap is much
  larger than the embed field's 1024), rather than reusing whatever
  the embed truncated to.
- Rebased onto a clean upstream main and dropped four unrelated
  fork-local commits (three explicitly tagged [carried], one
  untagged plugin symlink fix) that had accumulated on the source
  branch before this PR was cut -- this PR is Discord-only again.

Tests: tests/gateway/test_discord_clarify_buttons.py -- 5
truncation-behavior tests replaced with simpler "label is always
short" tests, 5 dict-unwrap tests updated to assert the full text
lands in the embed field rather than the button label, plus 1 new
boundary regression test for the field-cap fix. 21/21 pass. ruff
clean. git diff --check clean.
Require explicit user-visible context, render full numbered choices, and keep Discord controls compact with numbered action labels. Preserve canonical full-choice resolution and cover the executor, tool schema, Discord, Telegram compatibility, and docs.
@alt-glitch alt-glitch added type/feature New feature or request comp/tools Tool registry, model_tools, toolsets comp/plugins Plugin system and bundled plugins comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint platform/discord Discord bot adapter P3 Low — cosmetic, nice to have labels Jul 14, 2026
@RunLittleTurtle
RunLittleTurtle deleted the fix/clarify-context-rich branch July 14, 2026 15:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/plugins Plugin system and bundled plugins comp/tools Tool registry, model_tools, toolsets P3 Low — cosmetic, nice to have platform/discord Discord bot adapter type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants