From 937665a55c3da24105467bd2a4f56cc608d3a46f Mon Sep 17 00:00:00 2001 From: ryl0903 Date: Tue, 7 Apr 2026 17:26:24 +0800 Subject: [PATCH] fix(session): use parentID instead of timestamp for loop exit condition Replace timestamp-based comparison with parentID check to prevent duplicate assistant responses caused by clock skew between client and server. When client and server have different system times, the ID-based comparison lastUser.id < lastAssistant.id fails, causing the prompt loop to continue and generate a second assistant response. This fix uses the explicit parentID relationship to determine if the assistant message is a response to the last user message, which is immune to clock skew issues. For backward compatibility, the timestamp comparison is kept as a fallback for messages that may not have parentID set. Fixes #14935 --- packages/opencode/src/session/prompt.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index 24996c8d4b29..a9a1ef01243d 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -1374,7 +1374,14 @@ NOTE: At any point in time through this workflow you should feel free to ask the lastAssistant?.finish && !["tool-calls"].includes(lastAssistant.finish) && !hasToolCalls && - lastUser.id < lastAssistant.id + ( + // Use parentID to determine if assistant message is a response to the last user message. + // This is more reliable than timestamp comparison when client/server clocks are out of sync. + lastAssistant.parentID === lastUser.id || + // Fallback to timestamp comparison for backward compatibility with messages + // that may not have parentID set. + (!lastAssistant.parentID && lastUser.id < lastAssistant.id) + ) ) { log.info("exiting loop", { sessionID }) break