[Fix] Tasks loop when terminal chat replies time out - #1574
Draft
roomote-roomote[bot] wants to merge 2 commits into
Draft
[Fix] Tasks loop when terminal chat replies time out#1574roomote-roomote[bot] wants to merge 2 commits into
roomote-roomote[bot] wants to merge 2 commits into
Conversation
Contributor
|
No new code issues found. See task
Reviewed 6fc6adb |
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.
What changed
send_chat_replyfailures for closeout and clarification calls, including transport timeouts that never return a structured MCP tool result.missingChatCloseoutmetadata so the platform-owned fallback delivery path can surface the final response.Why this change was made
A chat-backed task could finish its implementation but remain active indefinitely when its terminal
send_chat_replycall timed out at the MCP client boundary. The closeout hook kept requesting another terminal reply because the existing delivery-failure accounting only ran after the MCP server returned a structured failure.The fallback decision also has to account for a timed-out MCP request that finishes successfully after the harness records its failure. A successful late delivery clears the persisted terminal-failure marker; using only the harness's in-memory latch would still request a second platform fallback.
Root cause analysis
The delivery path is OpenCode -> local Roomote MCP server -> worker HTTP relay ->
/api/mcp/slack/thread_reply-> Slack. The controller is not involved in this request path.OpenCode applies a 30-second default timeout to MCP tool requests. Roomote's worker relay allows a platform API request to run for up to 120 seconds per attempt, and the API handler may also wait on thread serialization, Slack thread verification, Slack retries, and post-delivery bookkeeping. The generated Roomote MCP configuration did not override OpenCode's shorter timeout, so OpenCode could return
MCP error -32001: Request timed outwhile the relay was still in flight.That client-side timeout bypassed the safeguard added for ordinary delivery failures:
recordFailedChatDeliveryResultonly sees a result afterhandleSendChatReplyreturns. With no recorded terminal failure, the stop hook continued to see an unsatisfied closeout and prompted the model to retry. The harness reminder counter did not solve retries initiated inside the model turn, and its state can be reset by later messages.The fix aligns the outer MCP timeout with the relay envelope and independently observes failed terminal reply tool events in the OpenCode harness. This ensures even transport-level failures consume the same persisted three-attempt budget. Fallback eligibility is then derived from that persisted state, which a successful late reply clears.
Impact
Slow chat delivery can now return its structured platform result instead of being cut off after 30 seconds. If delivery still fails three times, the task reaches a completed state, records one terminal warning, and hands the final response to the platform fallback rather than looping indefinitely. If an apparently timed-out reply succeeds before completion, Roomote recognizes that success and does not post a duplicate fallback.