Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions gradio/chat_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
from gradio.events import Dependency, EditData, SelectData
from gradio.flagging import ChatCSVLogger
from gradio.helpers import create_examples as Examples # noqa: N812
from gradio.helpers import special_args, update
from gradio.helpers import skip, special_args, update
from gradio.i18n import I18nData
from gradio.layouts import Accordion, Column, Group, Row

Expand Down Expand Up @@ -972,8 +972,11 @@ async def _stream_fn(
yield first_response, history_
else:
yield first_response, history_, *additional_outputs
except StopIteration:
yield None, history
except StopAsyncIteration:
if not self.additional_outputs:
yield None, history
else:
yield None, history, *([skip()] * len(self.additional_outputs))
async for response in generator:
if self.additional_outputs:
response, *additional_outputs = response
Expand Down
46 changes: 46 additions & 0 deletions test/test_chat_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ async def async_stream(message, history):
yield message[: i + 1]


def stream_or_nothing(message, history):
if message == "skip":
return
yield f"history_len={len(history)}"


async def async_stream_or_nothing(message, history):
if message == "skip":
return
yield f"history_len={len(history)}"


def count(message, history):
return str(len(history))

Expand Down Expand Up @@ -298,6 +310,40 @@ def test_streaming_api_async(self, connect):
wait([job])
assert job.outputs() == ["h", "he", "hel", "hell", "hello"]

def test_streaming_api_empty_generator(self, connect):
chatbot = gr.ChatInterface(stream_or_nothing).queue()
with connect(chatbot) as client:
assert client.predict("hello") == "history_len=0"
assert client.predict("skip") is None
# The skipped turn must leave the history intact and still record
# the user message, so the next turn sees three messages.
assert client.predict("hello") == "history_len=3"

def test_streaming_api_empty_generator_async(self, connect):
chatbot = gr.ChatInterface(async_stream_or_nothing).queue()
with connect(chatbot) as client:
assert client.predict("hello") == "history_len=0"
assert client.predict("skip") is None
assert client.predict("hello") == "history_len=3"

def test_streaming_api_empty_generator_with_additional_outputs(self, connect):
def stream_or_nothing_with_extra(message, history):
if message == "skip":
return
yield message, "extra"

with gr.Blocks() as demo:
code = gr.Code(render=False)
gr.ChatInterface(
stream_or_nothing_with_extra,
additional_outputs=[code],
api_name="chat",
)
code.render()
with connect(demo) as client:
assert client.predict("hello", api_name="/chat") == ("hello", "extra")
assert client.predict("skip", api_name="/chat") == (None, gr.skip())

def test_non_streaming_api(self, connect):
chatbot = gr.ChatInterface(double)
with connect(chatbot) as client:
Expand Down
Loading