Skip to content

Commit 251cd37

Browse files
Merge pull request google#75 from google/polling
Add configurable polling to the UI
2 parents 0f6ea90 + f6fd845 commit 251cd37

7 files changed

Lines changed: 84 additions & 11 deletions

File tree

demo/ui/components/async_poller.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,21 @@ class AsyncPoller extends LitElement {
77
static properties = {
88
triggerEvent: {type: String},
99
action: {type: Object},
10-
isRunning: {type: Boolean},
10+
polling_interval: {type: Number},
1111
};
1212

1313
render() {
1414
return html`<div></div>`;
1515
}
1616

1717
firstUpdated() {
18+
if (this.polling_interval <= 0) {
19+
return;
20+
}
1821
if (this.action) {
1922
setTimeout(() => {
2023
this.runTimeout(this.action)
21-
}, this.action.duration_seconds * 1000);
24+
}, this.polling_interval * 1000);
2225
}
2326
}
2427

@@ -28,9 +31,11 @@ class AsyncPoller extends LitElement {
2831
action: action,
2932
}),
3033
);
31-
setTimeout(() => {
32-
this.runTimeout(action);
33-
}, action.duration_seconds * 1000);
34+
if (this.polling_interval > 0) {
35+
setTimeout(() => {
36+
this.runTimeout();
37+
}, this.polling_interval * 1000);
38+
}
3439
}
3540
}
3641

demo/ui/components/async_poller.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,8 @@ def async_poller(
4040
events={
4141
"triggerEvent": trigger_event,
4242
},
43-
properties={"action": asdict(action) if action else {}},
43+
properties={
44+
"polling_interval": action.duration_seconds if action else 1,
45+
"action": asdict(action) if action else {}
46+
},
4447
)

demo/ui/components/conversation.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@
77
import threading
88

99
from state.state import AppState, SettingsState, StateMessage
10-
from state.host_agent_service import SendMessage, UpdateAppState, ListConversations
10+
from state.host_agent_service import SendMessage, ListConversations, convert_message_to_state
1111
from .chat_bubble import chat_bubble
1212
from .form_render import is_form, render_form, form_sent
1313
from .async_poller import async_poller, AsyncAction
14-
from state.host_agent_service import UpdateAppState
1514
from common.types import Message, TextPart
1615

1716

@@ -49,6 +48,16 @@ async def send_message(message: str, message_id: str = ""):
4948
metadata={'conversation_id': c.conversation_id if c else "",
5049
'conversation_name': c.name if c else ""},
5150
)
51+
# Add message to state until refresh replaces it.
52+
state_message = convert_message_to_state(request)
53+
if not app_state.messages:
54+
app_state.messages = []
55+
app_state.messages.append(state_message)
56+
conversation = next(filter(
57+
lambda x: x.conversation_id == c.conversation_id,
58+
app_state.conversations), None)
59+
if conversation:
60+
conversation.message_ids.append(state_message.message_id)
5261
response = await SendMessage(request)
5362

5463

demo/ui/components/header.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import mesop as me
2-
2+
from .poller import polling_buttons
33

44
@me.content_component
55
def header(title: str, icon: str):
@@ -19,4 +19,5 @@ def header(title: str, icon: str):
1919
type="headline-5",
2020
style=me.Style(font_family="Google Sans"),
2121
)
22-
me.slot()
22+
me.slot()
23+
polling_buttons()

demo/ui/components/page_scaffold.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from .side_nav import sidenav
55
from .async_poller import async_poller, AsyncAction
6+
from .poller import polling_buttons
67

78
from state.state import AppState
89
from state.host_agent_service import UpdateAppState
@@ -29,7 +30,11 @@ def page_scaffold():
2930

3031
app_state = me.state(AppState)
3132
action = (
32-
AsyncAction(value=app_state, duration_seconds=1) if app_state else None
33+
AsyncAction(
34+
value=app_state,
35+
duration_seconds=app_state.polling_interval)
36+
if app_state
37+
else None
3338
)
3439
async_poller(
3540
action=action, trigger_event=refresh_app_state

demo/ui/components/poller.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import mesop as me
2+
from state.state import AppState
3+
from state.host_agent_service import UpdateAppState
4+
5+
@me.content_component
6+
def polling_buttons():
7+
"""Polling buttons component"""
8+
state = me.state(AppState)
9+
with me.box(
10+
style=me.Style(
11+
display="flex",
12+
justify_content="end",
13+
)
14+
):
15+
me.button_toggle(
16+
value=[str(state.polling_interval)],
17+
buttons=[
18+
me.ButtonToggleButton(label="1s", value="1"),
19+
me.ButtonToggleButton(label="5s", value="5"),
20+
me.ButtonToggleButton(label="30s", value="30"),
21+
me.ButtonToggleButton(label="Disable", value="0")
22+
],
23+
multiple=False,
24+
hide_selection_indicator=True,
25+
disabled=False,
26+
on_change=on_change,
27+
style=me.Style(
28+
margin=me.Margin(bottom=20),
29+
30+
),
31+
)
32+
with me.content_button(
33+
type="raised",
34+
on_click=force_refresh,
35+
):
36+
me.icon("refresh")
37+
me.slot()
38+
39+
def on_change(e: me.ButtonToggleChangeEvent):
40+
state = me.state(AppState)
41+
state.polling_interval = int(e.values[0])
42+
43+
async def force_refresh(e: me.ClickEvent):
44+
"""Refresh app state event handler"""
45+
yield
46+
app_state = me.state(AppState)
47+
await UpdateAppState(app_state, app_state.current_conversation_id)
48+
yield
49+

demo/ui/state/state.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class AppState:
6565
completed_forms: dict[str, dict[str, Any] | None] = dataclasses.field(default_factory=dict)
6666
# This is used to track the message sent to agent with form data
6767
form_responses: dict[str, str] = dataclasses.field(default_factory=dict)
68+
polling_interval: int = 1
6869

6970
@me.stateclass
7071
class SettingsState:

0 commit comments

Comments
 (0)