-
Notifications
You must be signed in to change notification settings - Fork 3.5k
fix(core): move callbacks to the caller #5039
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
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 |
|---|---|---|
|
|
@@ -353,13 +353,22 @@ class _AudioOutput: | |
| first_frame_fut: asyncio.Future[float] | ||
| """Future that will be set with the timestamp of the first frame's capture""" | ||
|
|
||
| def _resolve_first_frame_fut(self, ev: io.PlaybackStartedEvent) -> None: | ||
| if not self.first_frame_fut.done(): | ||
| self.first_frame_fut.set_result(ev.created_at) | ||
|
|
||
|
|
||
| def perform_audio_forwarding( | ||
| *, | ||
| audio_output: io.AudioOutput, | ||
| tts_output: AsyncIterable[rtc.AudioFrame], | ||
| ) -> tuple[asyncio.Task[None], _AudioOutput]: | ||
| out = _AudioOutput(audio=[], first_frame_fut=asyncio.Future()) | ||
| # out.first_frame_fut should be cancelled in the caller after the playout is finished or interrupted | ||
| audio_output.on("playback_started", out._resolve_first_frame_fut) | ||
| out.first_frame_fut.add_done_callback( | ||
| lambda _: audio_output.off("playback_started", out._resolve_first_frame_fut) | ||
| ) | ||
|
Comment on lines
366
to
+371
Contributor
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. 🟡 Event listener cleanup on Previously, the Prompt for agentsWas this helpful? React with 👍 or 👎 to provide feedback. |
||
| task = asyncio.create_task(_audio_forwarding_task(audio_output, tts_output, out)) | ||
| return task, out | ||
|
|
||
|
|
@@ -372,12 +381,7 @@ async def _audio_forwarding_task( | |
| ) -> None: | ||
| resampler: rtc.AudioResampler | None = None | ||
|
|
||
| def _on_playback_started(ev: io.PlaybackStartedEvent) -> None: | ||
| if not out.first_frame_fut.done(): | ||
| out.first_frame_fut.set_result(ev.created_at) | ||
|
|
||
| try: | ||
| audio_output.on("playback_started", _on_playback_started) | ||
| audio_output.resume() | ||
|
|
||
| async for frame in tts_output: | ||
|
|
@@ -406,11 +410,6 @@ def _on_playback_started(ev: io.PlaybackStartedEvent) -> None: | |
| await audio_output.capture_frame(frame) | ||
|
|
||
| finally: | ||
| audio_output.off("playback_started", _on_playback_started) | ||
|
|
||
| if not out.first_frame_fut.done(): | ||
| out.first_frame_fut.cancel() | ||
|
|
||
| if isinstance(tts_output, _ACloseable): | ||
| try: | ||
| await tts_output.aclose() | ||
|
|
@@ -506,7 +505,7 @@ def _tool_completed(out: ToolExecutionOutput) -> None: | |
| ) | ||
| continue | ||
|
|
||
|
Contributor
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. 🟡 Same issue as BUG-0001 but in Was this helpful? React with 👍 or 👎 to provide feedback. |
||
| if not isinstance(function_tool, (llm.FunctionTool, llm.RawFunctionTool)): | ||
| if not isinstance(function_tool, llm.FunctionTool | llm.RawFunctionTool): | ||
| logger.error( | ||
| f"unknown tool type: {type(function_tool)}", | ||
| extra={ | ||
|
|
||
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.
🟡
isinstance(x, A | B)union syntax breaks Python 3.9 compatibilityAGENTS.md states "Python 3.9+ compatibility required" under Code Style. The change from
isinstance(tool, (llm.RawFunctionTool, llm.FunctionTool))toisinstance(tool, llm.RawFunctionTool | llm.FunctionTool)uses the PEP 604 union type syntax in a runtime expression, which requires Python 3.10+. On Python 3.9,type.__or__is not defined, sollm.RawFunctionTool | llm.FunctionToolraisesTypeError: unsupported operand type(s) for |: 'type' and 'type'. The old code using a tuple worked on all Python versions. Note: this applies only if the project still genuinely targets 3.9; ifpyproject.tomlhas since raised the minimum, this is moot.Was this helpful? React with 👍 or 👎 to provide feedback.