fix(clarify): show decision context and compact Discord choices - #64480
Closed
RunLittleTurtle wants to merge 2 commits into
Closed
fix(clarify): show decision context and compact Discord choices#64480RunLittleTurtle wants to merge 2 commits into
RunLittleTurtle wants to merge 2 commits into
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
contextfor model-generated clarify prompts1 · Approve) instead of numbers alone or clipped explanationsWhy
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:
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
contextis appended to the Python helper signature, so existing positional callback callers remain compatible.contextin the schema.Verification
Command:
Additional checks:
ruff checkon all changed Python files: passpython -m py_compileon production modules: passgit diff --check: pass