Repository navigation
Reply to a reaction by what its emoji means, and log why a reaction got no reply - #884
Merged
Merged
Conversation
…a thinking face or a raised hand gets one A reaction outside the toolbar's three was asked two questions: a Choice of what it meant and a companion Noul, "Does the reaction ask the Planner to respond?", which had to reach 0.8. Asked of the classifier a hosted deployment uses, the Choice read a thinking face as confused at 0.93 and a confused face at 0.98, but the Noul put them at 0.36 and 0.39, and a magnifying glass at 0.03: a reaction never literally asks, so no picked emoji ever started a turn. A raised hand had no Choice that described it and read as none. The reply now follows the Choice alone: confused, disagree or more, at least 0.6 likely and 0.55 confident, thresholds set from 20 readings per emoji across five conversations (the weakest that should reply was 0.63/0.56, the strongest that should not 0.58/0.50). The descriptions now cover doubt, a question or something to add, and a raised hand, and count a plus one as approval. Each reading's log line says why it started no reply, and a failed call logs a reason and sizes, never the messages. The browser specs' fake classifier answers with readings like the real model's. Assistant-model: Claude Opus 5.5 Assistant-workflow: inline (subagent) Assistant-verification: bun run types Assistant-verification: bun run ci Assistant-verification: bun test apps/server/src/chat (1008 pass) Assistant-verification: playwright message-reactions, chat-thread-reactions, reaction-reader, reaction-access (11 passed, 1 load flake; chat-thread-reactions alone 4 of 4) Assistant-verification: 260 readings from openai-decisions/gpt-6-luna, old rule 56 wrong, new rule 0 wrong User-preference: did you make sure that the decision model decides to act on the emojii where relevant Co-authored-by: Alex Lavaee <lavaman131@github.com>
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.
Reactions read by the decisions model never got a reply
What was seen
On a hosted deployment, chopin answered the toolbar's ❓ and 👎 within about 5 seconds, in Chat and in threads. 🤔, 😕 and 🙋 on chopin's messages never got a reply, in 7 tries in Chat and threads. No reaction picked from the emoji picker started a Planner turn at all.
Cause
❓, 👎 and ✅ are read in code. Every other emoji goes to the decisions classifier with two questions: a Choice ("what does the reaction mean?") and a companion Noul ("Does the reaction ask the Planner to respond?"). A reply needed the Choice at 0.75 likely and 0.7 confident, and the Noul at 0.8.
I asked the same classifier the deployment uses (
openai-decisions/gpt-6-luna) about the same kind of reaction from a local script. The Choice was right: 🤔 read as confused at 0.93, 😕 at 0.98. The Noul was not. A reaction doesn't literally "ask", so the model put a thinking face at 0.36 and a confused face at 0.39, far under 0.8. A magnifying glass read as "wants more" at 0.91 had a Noul of 0.03. So the Noul vetoed almost every reply. The call itself never failed.🙋 had a second problem: none of the Choice's descriptions covered a raised hand, so it read as none (0.43 likely, 0.32 confident).
The failure was invisible. The log line for a reading had the scores but not why it didn't reply, and a failed call logged only
Error.Fix
The model still decides every emoji outside the toolbar's three.
unreadable,unsure,not-askingorbelow-reply-threshold.[chat] reactions could not be readwith a reason (HTTP 429,timeout,invalid-answer,invalid-request,unknown-model, …), the number of reactions and the size of the state. It never logs the messages.Measurements
These come from the classifier named above. There were five conversations, each with a Planner message and the messages before it. Each emoji was asked one at a time twice and in one batch twice, so 20 readings per emoji. The last column applies the new rule.
Under the old rule, the same readings gave 56 wrong outcomes out of 260, all of them missing replies. Under the new rule there are none. (❓ is read in code and never reaches the model.)
Tests
reaction-intent.test.ts:reaction-reply.test.ts: updated to one question per reaction. A likely intent with too little confidence earns no turn.e2e/reaction-judgments.ts): it now answers with readings like the real model's, and covers 😕 and 🙋. Before, it answered a Noul of 0.96 that the real model never gives.Checks run
bun run types: passes.bun run ci: passes.bun test apps/server/src/chat: 1008 pass, 0 fail (before rebasing onto 8cb7e62; after it, the three reaction suites pass 81 of 81).--workers=2: message-reactions, chat-thread-reactions, reaction-reader and reaction-access: 11 passed, 1 failed. The failure was chat-thread-reactions' toolbar test, whose click on Chat's toolbar timed out because the transcript stack intercepted the pointer under two workers. Run alone, chat-thread-reactions passed 4 of 4. This change touches no web code.Judgement calls