forked from molecule-ai/molecule-core
fix(canvas): release sendInFlightRef in the activity-log WS path too
Third-pass review caught a fourth WS path I missed. The original fix + the stale-callback follow-up patched 3 sites that release the in-flight guards (pendingAgentMsgs effect, HTTP .then() success, HTTP .catch() success), but the ACTIVITY_LOGGED handler at lines 410-419 also clears `sending` + `sendingFromAPIRef` when the platform logs the workspace's a2a_receive ok/error. It only cleared 2 of the 3 refs — same exact bug class as the original. If THIS path wins the race (a2a_receive activity logged before pendingAgentMsgs delivers the reply text), sendInFlightRef stays stuck true and the next sendMessage() silently no-ops at line 464. Fix: route both branches (ok and error) through releaseSendGuards() so all four sites are now uniform. Updated the helper's docstring to explicitly list all four sites and warn that any future "I saw the reply" path that only clears the natural pair (sending + sendingFromAPIRef) will silently re-introduce the freeze. The disabled-button logic can't see sendInFlightRef so the visible state diverges from the synchronous re-entry guard otherwise. This is exactly the drift `releaseSendGuards()` was supposed to prevent — the helper landed in the prior commit but the activity-log site wasn't migrated to use it. Fixing now closes the gap. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
cacf499354
commit
f7ad5a82f7
@ -275,12 +275,15 @@ function MyChatPanel({ workspaceId, data }: Props) {
|
||||
// as if it were msg #2's reply.
|
||||
const sendTokenRef = useRef(0);
|
||||
|
||||
// Release every in-flight send guard at once. Keep the three sites
|
||||
// (WS push, HTTP .then() success, HTTP .catch() success) in lockstep
|
||||
// so a future contributor can't drop one and silently re-introduce
|
||||
// the post-WS Send-button freeze. `setSending(false)` is the only
|
||||
// observable user-side signal; the two refs are synchronous guards
|
||||
// the disabled-button logic can't see.
|
||||
// Release every in-flight send guard at once. Used by every site
|
||||
// that ends a send: pendingAgentMsgs WS push, ACTIVITY_LOGGED
|
||||
// a2a_receive ok/error WS event, HTTP .then() success, and HTTP
|
||||
// .catch() success. Keep these in lockstep — a future contributor
|
||||
// adding a new "I saw the reply" path that only clears `sending` +
|
||||
// `sendingFromAPIRef` (the natural pair) silently re-introduces
|
||||
// the post-WS Send-button freeze, because the disabled-button
|
||||
// logic can't see `sendInFlightRef` and so the visible state diverges
|
||||
// from the synchronous re-entry guard at line 464.
|
||||
const releaseSendGuards = useCallback(() => {
|
||||
setSending(false);
|
||||
sendingFromAPIRef.current = false;
|
||||
@ -408,15 +411,13 @@ function MyChatPanel({ workspaceId, data }: Props) {
|
||||
// via pendingAgentMsgs or the HTTP .then()).
|
||||
const own = (targetId || msg.workspace_id) === workspaceId;
|
||||
if (own && sendingFromAPIRef.current) {
|
||||
setSending(false);
|
||||
sendingFromAPIRef.current = false;
|
||||
releaseSendGuards();
|
||||
}
|
||||
} else if (status === "error") {
|
||||
line = `⚠ ${targetName} error`;
|
||||
const own = (targetId || msg.workspace_id) === workspaceId;
|
||||
if (own && sendingFromAPIRef.current) {
|
||||
setSending(false);
|
||||
sendingFromAPIRef.current = false;
|
||||
releaseSendGuards();
|
||||
setError("Agent error (Exception) — see workspace logs for details.");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user