fix: prevent agent loop self-reply caused by non-monotonic message IDs - #35872
fix: prevent agent loop self-reply caused by non-monotonic message IDs#35872lileilei-camera wants to merge 1 commit into
Conversation
Replace lexicographic string comparison of message IDs with timestamp-based comparison in the agent loop exit condition and the `MessageV2.latest()` function. `MessageID.ascending()` can produce IDs whose lexicographic order is inverted relative to creation time when two messages are created within the same millisecond (~2.8% probability). The string comparison `lastUser.id < lastAssistant.id` can evaluate to `false` even though the assistant message was created after the user message, causing the loop to continue processing the LLM's own output as if it were a new user message — producing hallucinated self-replies and phantom conversations. This is most visible in WebChat where the LLM asks clarifying questions and then immediately hallucinates a user response without any actual input. Root cause analysis: anomalyco#28986 Fixes: anomalyco#35741 Changes: - prompt.ts: exit condition uses time.created instead of id - message-v2.ts: latest() uses time.created instead of id (3 comparison sites)
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
|
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
|
This would be wonderful to get merged! I'm having to run a local build with this fix because GLM-5.2 is utterly unusable with this bug! |
|
Confirming this reproduces on v1.18.5 (macOS, Concrete example from a real session — one user message produced two
The assistant ID sorts lexicographically before the user ID ( Downstream effect: the model sees its own first answer in context and This matches the 2.8% collision rate documented in #28986. The fix is Maintainers please react to it! |
Issue for this PR
Closes #35741
Type of change
What does this PR do?
Fix the WebChat agent self-reply loop where the LLM hallucinates its own output as user input, producing 12+ rounds of self-reply in a single session.
Root cause: MessageID.ascending() generates IDs using a counter-based scheme where lexicographic string comparison can invert chronological order at ~2.8% probability under millisecond-dense creation. The loop exit condition in SessionPrompt.run and message selection in message-v2.ts both rely on lastUser.id < lastAssistant.id, which fails when IDs are non-monotonic.
Fix: Replace all message ID string comparisons with timestamp-based comparison (time.created):
This approach was inspired by the root cause analysis in #28986.
How did you verify your code works?
Screenshots / recordings
Not applicable - behavioral fix, no UI changes.
Checklist