Problem
Slack users can see the same final Hermes reply posted twice in a thread after a long streamed response.
Observed in a Slack thread on 2026-05-13: the gateway log showed the normal final send after a streamed/edited answer path, and the user reported the answer appeared twice.
Root cause hypothesis
GatewayStreamConsumer can display the complete final answer via an earlier streaming edit that still includes the cursor. If the later finalize=True edit fails transiently (Slack chat.update / rate-limit style failure), final_response_sent remains false. The outer gateway then assumes the final answer was not delivered and posts the full response again as a new message.
That fallback is correct when the visible preview is partial, but wrong when the visible streamed text already matches the final cleaned response.
Expected behavior
If the visible streamed message already equals the final cleaned response, a transient finalize edit failure should be treated as delivered. The gateway may best-effort strip the cursor, but it must not post the identical final body as a fresh message.
Acceptance criteria
- Add regression coverage for a streamed Slack-like response where the final edit fails after the previous visible message already contains the complete final content.
- Mark stream delivery as confirmed in that exact case so the normal gateway final-send path is suppressed.
- Preserve fallback behavior when only partial text is visible.
Problem
Slack users can see the same final Hermes reply posted twice in a thread after a long streamed response.
Observed in a Slack thread on 2026-05-13: the gateway log showed the normal final send after a streamed/edited answer path, and the user reported the answer appeared twice.
Root cause hypothesis
GatewayStreamConsumercan display the complete final answer via an earlier streaming edit that still includes the cursor. If the laterfinalize=Trueedit fails transiently (Slackchat.update/ rate-limit style failure),final_response_sentremains false. The outer gateway then assumes the final answer was not delivered and posts the full response again as a new message.That fallback is correct when the visible preview is partial, but wrong when the visible streamed text already matches the final cleaned response.
Expected behavior
If the visible streamed message already equals the final cleaned response, a transient finalize edit failure should be treated as delivered. The gateway may best-effort strip the cursor, but it must not post the identical final body as a fresh message.
Acceptance criteria