-
Notifications
You must be signed in to change notification settings - Fork 3.5k
gracefully stop AgentTask and parent agents when session close #4730
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
Changes from all commits
8953769
2e265d5
8f6a1bb
9236e7b
7720627
5d22bfe
ed50024
026de2e
522aafc
9424c15
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,7 +36,7 @@ | |
| from ..utils.misc import is_given | ||
| from . import io, room_io | ||
| from ._utils import _set_participant_attributes | ||
| from .agent import Agent | ||
| from .agent import Agent, AgentTask | ||
| from .agent_activity import AgentActivity | ||
| from .audio_recognition import TurnDetectionMode | ||
| from .client_events import ClientEventsHandler | ||
|
|
@@ -782,19 +782,30 @@ async def _aclose_impl( | |
| self._closing = True | ||
| self._cancel_user_away_timer() | ||
|
|
||
| if self._activity is not None: | ||
| activity = self._activity | ||
| while activity and isinstance(agent_task := activity.agent, AgentTask): | ||
| # notify AgentTask to complete and wait it to resume the parent agent | ||
| agent_task.cancel() | ||
| await agent_task._wait_for_inactive() | ||
|
|
||
| if old_agent := agent_task._old_agent: | ||
| activity = old_agent._activity | ||
| else: | ||
| break | ||
|
|
||
| if activity is not None: | ||
| if not drain: | ||
| try: | ||
| # force interrupt speeches when closing the session | ||
| await self._activity.interrupt(force=True) | ||
| await activity.interrupt(force=True) | ||
| except RuntimeError: | ||
| # uninterruptible speech | ||
| pass | ||
| await self._activity.drain() | ||
| await activity.drain() | ||
|
|
||
| # wait any uninterruptible speech to finish | ||
| if self._activity.current_speech: | ||
| await self._activity.current_speech | ||
| if activity.current_speech: | ||
| await activity.current_speech | ||
|
|
||
| # detach the inputs and outputs | ||
| self.input.audio = None | ||
|
|
@@ -804,13 +815,13 @@ async def _aclose_impl( | |
|
|
||
| if ( | ||
| reason != CloseReason.ERROR | ||
| and (audio_recognition := self._activity._audio_recognition) is not None | ||
| and (audio_recognition := activity._audio_recognition) is not None | ||
| ): | ||
| # wait for the user transcript to be committed | ||
| audio_recognition.commit_user_turn(audio_detached=True, transcript_timeout=2.0) | ||
|
|
||
| await self._activity.aclose() | ||
| self._activity = None | ||
| await activity.aclose() | ||
| self._activity = None | ||
|
|
||
| if self._agent_speaking_span: | ||
| self._agent_speaking_span.end() | ||
|
|
@@ -1068,12 +1079,21 @@ async def _update_activity( | |
| otel_context.attach(self._root_span_context) | ||
|
|
||
| previous_activity_v = self._activity | ||
| if self._activity is not None: | ||
| if (activity := self._activity) is not None: | ||
| if previous_activity == "close": | ||
| await self._activity.drain() | ||
| await self._activity.aclose() | ||
| await activity.drain() | ||
| await activity.aclose() | ||
| elif previous_activity == "pause": | ||
| await self._activity.pause(blocked_tasks=blocked_tasks or []) | ||
| await activity.pause(blocked_tasks=blocked_tasks or []) | ||
|
|
||
| if self._closing and new_activity == "start": | ||
| # disallow starting a new activity when the session is closing | ||
| logger.warning( | ||
| f"session is closing, skipping {new_activity} activity of {self._next_activity.agent.id}", | ||
| ) | ||
| self._next_activity = None | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: should we drain and close the new next activity first?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should be fine I guess, unless we later change the AgentActivity init to consume some resources. |
||
| self._activity = None | ||
| return | ||
|
|
||
| self._activity = self._next_activity | ||
|
longcw marked this conversation as resolved.
|
||
| self._next_activity = None | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.