Ver código fonte

Name the valid reactions when a prompt rejects one

A rejected reaction said only what it was not. The user hitting this
repeatedly had no way to learn what the card actually accepts — worst
on a clarify card, where a habitual green check is not an option by
design. Both feedback paths now state the valid reactions (the offered
numbers plus Other, or the card's own legend).
Paul Klumpp 5 dias atrás
pai
commit
cbe2ed0e82
2 arquivos alterados com 40 adições e 4 exclusões
  1. 15 4
      adapter.py
  2. 25 0
      test_adapter.py

+ 15 - 4
adapter.py

@@ -2114,10 +2114,17 @@ class ChattoAdapter(BasePlatformAdapter):
                         logger.debug("Chatto: prompt edit failed", exc_info=True)
                     return True
 
-            # Invalid emoji feedback.
+            # Invalid emoji feedback — name the options, so a rejected
+            # reaction teaches the valid ones instead of just refusing.
+            offered = [
+                _PROMPT_NUMBER_EMOJIS[i]
+                for i in range(min(len(choices), len(_PROMPT_NUMBER_EMOJIS)))
+            ]
             try:
                 await self.send(
-                    room_id, "That reaction isn't a valid option for this prompt."
+                    room_id,
+                    "That reaction isn't a valid option for this prompt. "
+                    f"React with {', '.join([*offered, _PROMPT_OTHER_EMOJI])}.",
                 )
             except Exception:
                 logger.debug("Chatto: invalid reaction feedback failed", exc_info=True)
@@ -2145,10 +2152,14 @@ class ChattoAdapter(BasePlatformAdapter):
                 logger.debug("Chatto: prompt edit failed", exc_info=True)
             return True
 
-        # Invalid emoji feedback.
+        # Invalid emoji feedback — the card's legend is the shortest correct
+        # list of what *is* valid here, so repeat it verbatim.
+        legend = ", ".join(f"{key} {choice}" for key, choice in choices_map.items())
         try:
             await self.send(
-                room_id, "That reaction isn't a valid option for this prompt."
+                room_id,
+                "That reaction isn't a valid option for this prompt. "
+                f"Valid on this card: {legend}.",
             )
         except Exception:
             logger.debug("Chatto: invalid reaction feedback failed", exc_info=True)

+ 25 - 0
test_adapter.py

@@ -1428,6 +1428,19 @@ class TestInteractiveReactionRouting:
 
         assert "prompt-1" in adapter._clarify_prompts
 
+    async def test_invalid_clarify_feedback_names_the_options(self, adapter):
+        """The rejection must teach the valid reactions — a ✅ on a clarify
+        card is not an option by design, and the answer has to say which are."""
+        self._clarify(adapter)
+        adapter._chatto_client.post_message = AsyncMock(
+            return_value=_make_message(body="ack", message_id="ack-1")
+        )
+        await adapter._handle_realtime_event(self._event("✅"))
+
+        body = adapter._chatto_client.post_message.await_args.kwargs["body"]
+        assert "React with 1️⃣, 2️⃣, ✏️" in body
+        assert "🚀" not in body
+
     async def test_the_other_emoji_reaction_is_recognized(self, adapter):
         """✏️ routes to the awaiting-text path — the keycap-style normalization
         must not have lost the Other button."""
@@ -1471,6 +1484,18 @@ class TestInteractiveReactionRouting:
         resolve.assert_not_called()
         assert "prompt-1" in adapter._approval_prompts
 
+    async def test_invalid_approval_feedback_repeats_the_legend(self, adapter):
+        """The card's legend is the truth about what is valid here — the
+        rejection repeats it instead of leaving the user guessing."""
+        self._approval(adapter, choices_map={"✅": "once", "❌": "deny"})
+        adapter._chatto_client.post_message = AsyncMock(
+            return_value=_make_message(body="ack", message_id="ack-1")
+        )
+        await adapter._handle_realtime_event(self._event("🚀"))
+
+        body = adapter._chatto_client.post_message.await_args.kwargs["body"]
+        assert "✅ once" in body and "❌ deny" in body
+
 
 # -- Prompt card threading --