-
Notifications
You must be signed in to change notification settings - Fork 194
Description
This issue is for a: (mark with an x)
- [X] bug report -> please search issues before submitting
- [ ] feature request
- [ ] documentation issue or request
- [ ] regression (a behavior that used to work and stopped in a new release)
Minimal steps to reproduce
I discovered this bug in the middle-tier demo.
In the Python Fast-API middle-tier demo, it uses await self.client.generate_response() for text user input and self.client.events() for audio stuff.
Try to send text user input more than once, and you will see the second one is blocked by the first one. because await self.client.generate_response() never resolves.
In cause you also cannot run the middle-tier demo, here is my PR to fix the demo (not fixing this issue): #110
Any log messages given by the failure
Expected/desired behavior
We can send text messages and audio messages as many as we want in any order.
OS and Version?
macOS
Versions
Python rtclient-0.5.3
Mention any other details that might be useful
RTClient.generate_response wait for response.created event:
async def generate_response(self) -> RTResponse:
await self._client.send(ResponseCreateMessage())
message = await self._message_queue.receive(lambda m: m.type == "response.created")
...RTClient.events wait for response.created event as well:
async def events(self) -> AsyncGenerator[RTInputAudioItem | RTResponse]:
# TODO: Add the updated quota message as a control type of event.
while True:
message = await self._message_queue.receive(
lambda m: m.type == "input_audio_buffer.speech_started" or m.type == "response.created"
)
...The below code from message_queue.py shows why only one of the functions above can get the response.created event, but not both:
def _find_and_remove(self, predicate: Callable[[T], bool]) -> Optional[T]:
for i, message in enumerate(self._stored_messages):
if predicate(message):
return self._stored_messages.pop(i)
return None
async def receive(self, predicate: Callable[[T], bool]) -> Optional[T]:
# The first one who takes the message will remove it from the queue as well.
found_message = self._find_and_remove(predicate)
....