-
Notifications
You must be signed in to change notification settings - Fork 202
Improve AgentActivity resource cleanup #891
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🦋 Changeset detectedLatest commit: cecac00 The changes in this PR will be included in the next version bump. This PR includes changesets to release 15 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 |
|
We have multiple agents with handoffs, the close handler is only called if the instance is draining / closing. So as long as the session is not closed, it should not close anything? Or what I'm missing here? Can you show a test or a demo where this happens? Looking at the code it also stops the main queue during cleanup, so do you start another session and the new session is then broken? |
The
You can try running |
|
I'm working on a fix right now. |
| _recognize(frame: AudioFrame): Promise<SpeechEvent> { | ||
| return this.#stt.recognize(frame); | ||
| _recognize(frame: AudioFrame, abortSignal?: AbortSignal): Promise<SpeechEvent> { | ||
| return this.#stt.recognize(frame, abortSignal); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
plugins can now attach this abortSignal for any external request cancellation
| private logger = log(); | ||
| private _connOptions: APIConnectOptions; | ||
|
|
||
| protected abortController = new AbortController(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add an abortController in root STT class, which mainly handles any external request cancellation such as fetch. abortSignal will be aborted whenever the underling STT stream is closed.
agents/src/voice/agent.ts
Outdated
| ); | ||
| } | ||
| wrapped_stt = new STTStreamAdapter(wrapped_stt, agent.vad); | ||
| wrapped_stt = new STTStreamAdapter(wrapped_stt, activity.vad); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix a minor bug on non-streaming STT, allowing vad on AgentSession to forward to Agent if not set explicitly
| const cleanup = () => { | ||
| if (cleaned) return; | ||
| cleaned = true; | ||
| stream.close(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^ stream.close() in STT / TTS / LLM stream should be the method that plugin uses to do proper resource cancellation. @simllll @KrishnaShuk
| samples100Ms, | ||
| ); | ||
|
|
||
| const abortPromise = waitForAbort(this.abortSignal); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor bug fix: prevent overflowing max #listeners
|
@toubatbrian just to confirm my understanding: the new pattern will be that the base SpeechStream (and SynthesizeStream, etc.) will have its own AbortController, and plugins should use this.abortSignal for any internal async operations, correct? |
|
@KrishnaShuk yes, the btw there's the PR for TTS resource cleanup #893, let me know your thoughts! |
|
So after merging of both PRs (this one and #893) the resource cleanup issue is fully resolved right? |
After those 2 PRs I still need to handle cleanup on LLM nodes, but after all those been done the issue should be fully resolved |
Problem
Previously we have #849 which adds
close()call to STT / TTS / VAD on agent activity close and subsequently #883. Turned out these are not correct way of handling resource cleanup, because there could be another AgentActivity starts after the closed activity, i.e. agent transfer. However, the close() method on STT / TTS are "global" w.r.t the STT / TTS class, meaning aborting the class object not only cancels any active stt / tts stream, but also make STT / TTS unusable for any future streams created under this STT / TTS object, making the speeches after agent transfer failed.Fix
sttNodellmNodeandttsNodeto always callclose()on respective stream objects created from globalSTTTTSLLMcomponent, allowing plugins to implement proper resource cleanup insideSpeechStreamSynthsizeStreamandLLMStreaminstead of on the root class.Future TODOs