Reusable Realtime Session across Handoffs & Agent Tasks#1193
Reusable Realtime Session across Handoffs & Agent Tasks#1193toubatbrian merged 10 commits intobrian/reuse-sttfrom
Conversation
🦋 Changeset detectedLatest commit: 4b4f251 The changes in this PR will be included in the next version bump. This PR includes changesets to release 22 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
💡 Codex ReviewLines 960 to 963 in 58726f4
agents-js/agents/src/voice/agent_activity.ts Lines 829 to 830 in 58726f4 The new realtime agents-js/agents/src/stream/deferred_stream.ts Lines 87 to 89 in 58726f4
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
…#1220) Co-authored-by: Qiong Zhou Huang <qiong@phonic.co> Co-authored-by: Brian Yin <brian.yin@livekit.io>
| this.closeCurrentGeneration({ interrupted: false }); | ||
| return this.startNewAssistantTurn({ userInitiated: true }); | ||
| this.pendingGenerateReplyFut = new Future<llm.GenerationCreatedEvent>(); | ||
| this.sendGenerateReply(instructions, requestId); |
There was a problem hiding this comment.
🔴 Floating promise in Phonic generateReply can cause indefinite caller hang
In generateReply(), this.sendGenerateReply(instructions, requestId) at line 486 is called without await, void, or .catch(). The sendGenerateReply method is async and can throw after the await this.readyToStart.await (e.g., if this.socket.sendGenerateReply(...) at line 505 throws because the socket just closed). If this happens, the thrown error becomes an unhandled promise rejection AND this.pendingGenerateReplyFut is never resolved or rejected, causing the caller of generateReply() (which awaits this.pendingGenerateReplyFut.await at line 488) to hang indefinitely.
Prompt for agents
In plugins/phonic/src/realtime/realtime_model.ts, the generateReply method at line 486 calls this.sendGenerateReply(instructions, requestId) without awaiting or catching the returned promise. The sendGenerateReply method is async and can throw after its internal await (e.g. if socket.sendGenerateReply throws). This leaves pendingGenerateReplyFut unresolved, hanging the caller forever.
The fix should wrap the socket send inside sendGenerateReply in a try/catch that rejects pendingGenerateReplyFut on error. Alternatively, the call in generateReply could be changed to something like:
void this.sendGenerateReply(instructions, requestId).catch((error) => {
if (this.pendingGenerateReplyFut && !this.pendingGenerateReplyFut.done) {
this.pendingGenerateReplyFut.reject(error);
this.pendingGenerateReplyFut = undefined;
}
});
Either approach ensures that if sendGenerateReply fails, pendingGenerateReplyFut is rejected so the caller does not hang indefinitely.
Was this helpful? React with 👍 or 👎 to provide feedback.
No description provided.