You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On a new chat, the first send captures the effort pick (X) and the server stores it on the chat it opens. If the user changes the picker to Y while that send is still pending, the change goes to newChatEffort (there is no chat id yet). On admission, useChat adopted the captured X onto the new chat and cleared newChatEffort, so Y was lost: the picker showed X and the next turn ran at X. The dedup-conflict adoption (409 naming the chat the first attempt opened) had the same problem.
Adopting newChatEffort ?? effortChoice locally is not enough on its own: admission already stored X on the server, so a reload would bring X back.
Fix
At admission, useChat reads the live new-chat pick. If it differs from the pick the send carried, it adopts it locally and saves it to the chat through the existing per-chat effort save (PUT /api/mothership/chats/[chatId]/effort), so local and server state agree. A failed save rolls back by pick token as before, falling back to the stored value. If the pick is unset or unchanged, behaviour is unchanged and no extra save fires.
On a dedup conflict (409 naming the chat an earlier attempt opened), the client cannot know which pick that attempt stored, so it adopts the latest pick and always saves it.
The effort mutation's options move into one factory. useSetMothershipChatEffort(chatId) is unchanged; a new saveMothershipChatEffort(queryClient, chatId, effort) runs the same mutation through a MutationObserver for a chat id learned mid-send. Both use the same per-chat scope, so the admission save and any later composer pick for that chat land in order, and other chats never wait on it.
Test plan
New use-chat.dom.test.tsx case: pick low, send, change the pick to high while the send is pending, admit. Asserts the chat keeps high and exactly one effort save goes to that chat. Fails on current staging (expected 'low' to be 'high'), passes with the fix.
Same case with the pick unchanged asserts no effort save fires.
New dedup case: a 409 naming the earlier attempt's chat adopts the latest pick and saves it to that chat. Also fails on current staging, passes with the fix.
Existing effort mutation test passes unchanged.
tsc --noEmit, biome, check:audits, and the home hooks, user-input, mothership-chats, effort store, and organization-home suites pass.
[Medium risk] Saves chat effort preference when a new message opens a chat.
The PR appears safe to merge; no outstanding findings remain.
Summary
The PR preserves an effort pick changed during a new chat’s first pending send and saves that pick to the admitted chat. It also covers deduplicated admission and keeps effort saves ordered per chat. Both previous Greptile findings are resolved.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
A[Send with captured effort] --> B[Chat admitted or identified by 409]
B --> C[Read latest new-chat pick]
C --> D[Adopt pick for chat]
D --> E{Pick changed or 409?}
E -- Yes --> F[Save through per-chat mutation scope]
E -- No --> G[No additional save]
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
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
Raised by cubic on the release PR: #8654 (comment)
On a new chat, the first send captures the effort pick (X) and the server stores it on the chat it opens. If the user changes the picker to Y while that send is still pending, the change goes to
newChatEffort(there is no chat id yet). On admission,useChatadopted the captured X onto the new chat and clearednewChatEffort, so Y was lost: the picker showed X and the next turn ran at X. The dedup-conflict adoption (409naming the chat the first attempt opened) had the same problem.Adopting
newChatEffort ?? effortChoicelocally is not enough on its own: admission already stored X on the server, so a reload would bring X back.Fix
useChatreads the live new-chat pick. If it differs from the pick the send carried, it adopts it locally and saves it to the chat through the existing per-chat effort save (PUT /api/mothership/chats/[chatId]/effort), so local and server state agree. A failed save rolls back by pick token as before, falling back to the stored value. If the pick is unset or unchanged, behaviour is unchanged and no extra save fires.409naming the chat an earlier attempt opened), the client cannot know which pick that attempt stored, so it adopts the latest pick and always saves it.useSetMothershipChatEffort(chatId)is unchanged; a newsaveMothershipChatEffort(queryClient, chatId, effort)runs the same mutation through aMutationObserverfor a chat id learned mid-send. Both use the same per-chat scope, so the admission save and any later composer pick for that chat land in order, and other chats never wait on it.Test plan
use-chat.dom.test.tsxcase: picklow, send, change the pick tohighwhile the send is pending, admit. Asserts the chat keepshighand exactly one effort save goes to that chat. Fails on current staging (expected 'low' to be 'high'), passes with the fix.409naming the earlier attempt's chat adopts the latest pick and saves it to that chat. Also fails on current staging, passes with the fix.tsc --noEmit, biome,check:audits, and the home hooks, user-input, mothership-chats, effort store, and organization-home suites pass.