Skip to content
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

remove static while pending behaviour #7410

Merged
merged 9 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
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
6 changes: 6 additions & 0 deletions .changeset/crazy-ghosts-run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@gradio/app": patch
"gradio": patch
---

fix:remove static while pending behaviour
2 changes: 1 addition & 1 deletion demo/chatinterface_streaming_echo/run.ipynb
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: chatinterface_streaming_echo"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import time\n", "import gradio as gr\n", "\n", "def slow_echo(message, history):\n", " for i in range(len(message)):\n", " time.sleep(0.05)\n", " yield \"You typed: \" + message[: i+1]\n", "\n", "demo = gr.ChatInterface(slow_echo).queue()\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: chatinterface_streaming_echo"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import time\n", "import gradio as gr\n", "\n", "\n", "def slow_echo(message, history):\n", " for i in range(len(message)):\n", " yield \"You typed: \" + message[: i + 1]\n", "\n", "\n", "demo = gr.ChatInterface(slow_echo).queue()\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
5 changes: 3 additions & 2 deletions demo/chatinterface_streaming_echo/run.py
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason you removed the time.sleep? Without it, its not as clear that this is a streaming demo

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clear in what way? It returns an iterator.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meaning visually when you run the demo, the text appears all at once, instead of the characters appearing one by one

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This demo is used in the docs here:

$demo_chatinterface_streaming_echo

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, we should really have dedicated demo's for tests. WIll fix.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll create a new demo because i need to tweak the demo to fix the tests.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can use the _test suffix for designating test demos

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a prefix, so they are easier to find in the fs?

Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import time
import gradio as gr


def slow_echo(message, history):
for i in range(len(message)):
time.sleep(0.05)
yield "You typed: " + message[: i+1]
yield "You typed: " + message[: i + 1]


demo = gr.ChatInterface(slow_echo).queue()

Expand Down
17 changes: 1 addition & 16 deletions js/app/src/Blocks.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -525,22 +525,7 @@
.on("status", ({ fn_index, ...status }) => {
tick().then(() => {
const outputs = dependencies[fn_index].outputs;
outputs.forEach((id) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also delete the line above (508) which defines const pending_outputs: number[] = [];

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also have some additional logic involving outputs_set_to_non_interactive that can be deleted

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeh.

if (
instance_map[id].props.interactive &&
status.stage === "pending" &&
dep.targets[0][1] !== "focus"
) {
pending_outputs.push(id);
instance_map[id].props.interactive = false;
} else if (
["complete", "error"].includes(status.stage) &&
pending_outputs.includes(id) &&
!outputs_set_to_non_interactive.includes(id)
) {
instance_map[id].props.interactive = true;
}
});

//@ts-ignore
loading_status.update({
...status,
Expand Down
23 changes: 12 additions & 11 deletions js/app/test/chatinterface_streaming_echo.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,24 @@ import { test, expect } from "@gradio/tootils";
test("chatinterface works with streaming functions and all buttons behave as expected", async ({
page
}) => {
const submit_button = await page.getByRole("button", { name: "Submit" });
const retry_button = await page.getByRole("button", { name: "🔄 Retry" });
const undo_button = await page.getByRole("button", { name: "↩️ Undo" });
const clear_button = await page.getByRole("button", { name: "🗑️ Clear" });
const textbox = await page.getByPlaceholder("Type a message...");
const submit_button = page.getByRole("button", { name: "Submit" });
const retry_button = page.getByRole("button", { name: "🔄 Retry" });
const undo_button = page.getByRole("button", { name: "↩️ Undo" });
const clear_button = page.getByRole("button", { name: "🗑️ Clear" });
const textbox = page.getByPlaceholder("Type a message...");

await textbox.fill("hello");
await submit_button.click();
await expect(textbox).toHaveValue("");
const bot_message_0 = await page.locator(".bot.message").nth(0);
const bot_message_0 = page.locator(".bot.message").nth(0);
await expect(bot_message_0).toContainText("You typed: hello");

await textbox.fill("hi");
await submit_button.click();
await expect(textbox).toHaveValue("");
const bot_message_1 = await page.locator(".bot").nth(1);
const bot_message_1 = page.locator(".bot").nth(1);
await expect(bot_message_1).toContainText("You typed: hi");

await retry_button.click();
await expect(textbox).toHaveValue("");
await expect(page.locator(".bot").nth(1)).toContainText("You typed: hi");

await undo_button.click();
await expect
.poll(async () => page.locator(".message.bot").count(), { timeout: 5000 })
Expand All @@ -36,6 +32,11 @@ test("chatinterface works with streaming functions and all buttons behave as exp
await expect(textbox).toHaveValue("");
await expect(page.locator(".bot").nth(1)).toContainText("You typed: salaam");

// TODO: This isn't testing anyting and is introducing flake, needs addressing.
// await retry_button.click();
// await expect(textbox).toHaveValue("");
// await expect(page.locator(".bot").nth(1)).toContainText("You typed: salaam");

await clear_button.click();
await expect
.poll(async () => page.locator(".bot.message").count(), { timeout: 5000 })
Expand Down