fix: prevent agent participants getting stuck in private chat#1053
Open
m9h wants to merge 1 commit intoPAIR-code:mainfrom
Open
fix: prevent agent participants getting stuck in private chat#1053m9h wants to merge 1 commit intoPAIR-code:mainfrom
m9h wants to merge 1 commit intoPAIR-code:mainfrom
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
Collaborator
|
Hi @m9h -- thanks for the PR! It seems to have a lot of unrelated commits? |
Author
|
Sorry about that @rasmi. Those weren't supposed to be included. I will clean this up as soon as I can get back to it. |
…ode#1011, PAIR-code#938) Two related bugs cause private chat stages to hang indefinitely: 1. When a mediator returns shouldRespond: false (PAIR-code#938), no message is written to Firestore. The frontend spinner hangs for 120s because there's no signal that the mediator chose not to respond. 2. When a mediator hits maxResponses or returns readyToEndChat with an empty message (PAIR-code#1011), agent participants never get triggered because they only respond to MEDIATOR-type messages. No new message is written, so the agent is stuck forever. Fix: When a mediator can no longer respond (maxResponses reached or shouldRespond: false), send a system message ("<name> has left the chat") to the private chat. This: - Stops the frontend spinner (system message sender != participant) - Triggers agent participants to act (they now also respond to SYSTEM messages, not just MEDIATOR messages) - Uses trigger log deduplication to prevent infinite loops - Moves the empty-text check after shouldRespond/readyToEndChat extraction so structured output signals aren't treated as failures Changes: - chat.agent.ts: Send "left the chat" system message when mediator can't respond; handle shouldRespond:false for mediator type; reorder empty-text check to respect structured output signals - chat.utils.ts: Add sendSystemPrivateChatMessage() utility - chat.triggers.ts: Skip mediator responses to system messages; allow agent participants to respond to system messages Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
95eaeab to
e00787c
Compare
Member
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.
Summary
Fixes #1011 and #938 — two related bugs that cause private chat stages to hang indefinitely.
Bug 1: Spinner hangs when mediator returns
shouldRespond: false(#938)When a mediator's structured output includes
shouldRespond: false, no message is written to Firestore. The frontend has no signal, so the "Waiting for a response..." spinner hangs for 120 seconds until the timeout fires.Bug 2: Agent participants get stuck in private chat (#1011)
When a mediator reaches
maxResponsesor returnsreadyToEndChat: truewith an empty message, no new chat document is created. Agent participants only respond toUserType.MEDIATORmessages, so they never get triggered and the experiment is stuck forever.Root cause
Both bugs share the same root cause: when a mediator stops responding (for any reason), no Firestore document is written, so neither the frontend nor agent participants receive a signal.
Fix
When a mediator can no longer respond, send a system message (
"<Name> has left the chat.") to the private chat collection. This:senderIddiffers from the participant'spublicId, breaking theisWaitingForResponseconditionUserType.SYSTEMmessages (in addition toUserType.MEDIATOR), so they can setreadyToEndChatand advanceleft-chat-{publicId}) to prevent infinite loops (system message → trigger → mediator can't respond → system message → ...)Also moves the empty-text failure check (
!response.text) to after structured output extraction, soshouldRespond: falseandreadyToEndChat: truewith empty text aren't incorrectly treated as API failures.Changes
functions/src/chat/chat.agent.tsmaxResponsesor returnsshouldRespond: false; reorder empty-text checkfunctions/src/chat/chat.utils.tssendSystemPrivateChatMessage()utilityfunctions/src/triggers/chat.triggers.tsTest plan
maxResponses: 3— verify system message appears after 3rd response and agent advancesshouldRespond: falsevia structured output — verify spinner stops immediately and system message appearsshouldRespond/maxResponses) — verify no regression🤖 Generated with Claude Code