GUI Protocol Messages¶
In a nutshell
This page is the wire-level message catalog for the legacy Qt WebSocket GUI protocol: every mycroft.session.*, mycroft.gui.list.*, and mycroft.events.triggered message shape, with JSON examples. For the conceptual picture (what the protocol is for, the messagebus messages skills send, and the client architecture), see GUI Protocol. For terms, see the Glossary.
The OVOS GUI is deprecated: see Screens on OVOS Today for the full picture
This page documents the legacy protocol. There is no generally usable OVOS GUI, and a replacement is Upcoming. Building a remote client? Skip this legacy protocol and see Screens on OVOS Today for the current approach.
Qt WebSocket Protocol (Legacy Adapter)¶
This section applies only when
ovos-legacy-mycroft-gui-pluginis installed.
All messages are JSON objects sent over the WebSocket connection at ws://localhost:18181/gui.
Connection handshake¶
Qt client → ovos-gui (OVOS messagebus):
{
"type": "mycroft.gui.connected",
"data": {
"gui_id": "unique_identifier_provided_by_client",
"framework": "qt5"
}
}
ovos-gui → Qt client (OVOS messagebus reply):
{
"type": "mycroft.gui.port",
"data": {
"port": 18181,
"gui_id": "qt-client-1",
"framework": "qt5"
}
}
The Qt client then opens a WebSocket connection to ws://localhost:18181/gui.
Try it: connect a raw WebSocket client to 18181
You don't need a Qt client to see this handshake happen. With ovos-gui running and the
legacy adapter installed, connect any WebSocket client to ws://localhost:18181/gui (for
example websocat ws://localhost:18181/gui or a short websockets Python script) and trigger
a skill that shows a GUI page. You should observe the server immediately replay
mycroft.session.list.insert and mycroft.gui.list.insert messages for the active
namespace. This is GUIWebsocketHandler.synchronize() bringing your new client up to date.
When a client connects, GUIWebsocketHandler.synchronize() replays the full current state:
-
Re-sends
mycroft.session.list.insertfor every namespace in the active stack (in order). -
For each namespace, re-sends
mycroft.gui.list.insertwith its current QML page. -
Re-emits all
mycroft.session.setmessages for every key innamespace.data.
Namespace stack management (mycroft.system.active_skills)¶
The reserved namespace mycroft.system.active_skills defines the display priority.
The first item is always the namespace currently shown.
Insert namespace (skill becomes visible):
{
"type": "mycroft.session.list.insert",
"namespace": "mycroft.system.active_skills",
"position": 0,
"data": [{"skill_id": "ovos-skill-weather"}]
}
Move namespace (existing skill re-activated):
{
"type": "mycroft.session.list.move",
"namespace": "mycroft.system.active_skills",
"from": 2,
"to": 0,
"items_number": 1
}
Remove namespace (skill cleared / idle):
{
"type": "mycroft.session.list.remove",
"namespace": "mycroft.system.active_skills",
"position": 0,
"items_number": 1
}
Session data sync (mycroft.session.*)¶
Session data is a key/value dictionary kept synchronized between ovos-gui and each
Qt client. Values may be strings, numbers, booleans, or lists.
Set / update a key:
{
"type": "mycroft.session.set",
"namespace": "ovos-skill-weather",
"data": {
"current_temp": 22,
"condition": "Sunny"
}
}
Delete a key:
List operations. The shipping service emits mycroft.session.list.* messages only for
the reserved mycroft.system.active_skills namespace stack, always with a data key —
there is no per-skill list-property protocol (and no mycroft.session.list.update
producer at all). A namespace entering the active stack:
{
"type": "mycroft.session.list.insert",
"namespace": "mycroft.system.active_skills",
"position": 0,
"data": [{"skill_id": "ovos-skill-weather.openvoiceos"}]
}
An already-active namespace moving to the front:
{
"type": "mycroft.session.list.move",
"namespace": "mycroft.system.active_skills",
"from": 2,
"to": 0,
"items_number": 1
}
A namespace leaving the stack:
{
"type": "mycroft.session.list.remove",
"namespace": "mycroft.system.active_skills",
"position": 2,
"items_number": 1
}
Page management (mycroft.gui.list.*)¶
Each active skill is associated with a list of page URIs.
Insert new page at position:
{
"type": "mycroft.gui.list.insert",
"namespace": "ovos-skill-weather",
"position": 0,
"data": [{"url": "/home/ovos/.cache/ovos_gui/system/qt5/SYSTEM_TextFrame.qml", "page": "SYSTEM_TextFrame"}]
}
The url is an absolute path into the GUI resource cache, resolved server-side by
ovos-gui (pages whose name starts with SYSTEM resolve under the shared system
resource namespace instead of the skill's own). When the server cannot resolve a page,
url is null and the client is responsible for resolving the page from namespace
and page name.
Move pages:
{
"type": "mycroft.gui.list.move",
"namespace": "ovos-skill-weather",
"from": 0,
"to": 2,
"items_number": 1
}
Remove pages:
{
"type": "mycroft.gui.list.remove",
"namespace": "ovos-skill-weather",
"position": 0,
"items_number": 1
}
Events (mycroft.events.triggered)¶
Events can be emitted by the GUI client (e.g. user tapped a button) or by the skill (e.g. a voice command caused a state change).
{
"type": "mycroft.events.triggered",
"namespace": "ovos-skill-weather",
"event_name": "my.gui.event",
"data": {"item": 3}
}
In this core → client direction the payload key is data. The opposite direction (client →
core) carries the payload under parameters instead.
Page focus / interaction (client → core)¶
When the user swipes to a different page or interacts with one, the Qt client signals
core. ovos-gui listens for gui.page_gained_focus and gui.page_interaction on the
OVOS bus. Both carry skill_id and a zero-based page_number. The interaction event also
resets the namespace's idle-removal timer.
System status events¶
Core bus events forwarded to Qt clients:
{
"type": "mycroft.events.triggered",
"namespace": "system",
"event_name": "recognizer_loop:wakeword",
"data": {}
}
Qt client → OVOS core bus¶
Messages received from Qt clients over the WebSocket are forwarded to the OVOS core bus unchanged. This allows Qt GUI interactions (button presses, text input) to reach skills as normal bus events.
Summary: message flow¶
Skill call: self.gui.show_text("Hello", title="Greeting")
→ bus: gui.value.set (skill namespace data)
→ bus: gui.page.show (SYSTEM_TextFrame)
→ ovos-gui: NamespaceManager records page + data on the namespace
→ WS: mycroft.session.list.insert (namespace into active stack)
→ WS: mycroft.gui.list.insert (page SYSTEM_TextFrame, resolved url)
→ WS: mycroft.session.set (sync data to Qt)
→ Qt client renders the page
User swipes / taps on Qt:
→ WS → bus: gui.page_gained_focus / gui.page_interaction (skill_id, page_number)
→ ovos-gui updates focused page and reschedules namespace timeout
Upcoming: unreleased
In the GUI-rework, specified by the OVOS-GUI-1 spec (see GUI Service), the bus contract changes:
gui.page.showwill accept onlySYSTEM_*template names. Custom QML pages are no longer supported.- Instead of mirroring to Qt clients directly, template events fan out to every loaded
opm.gui_adapterplugin (see GUI Adapter Plugins). The Qt WebSocket protocol on this page becomes one such adapter.
None of this is implemented in ovos-gui yet. See
GUI Adapter Plugins for what the adapter plugins being built ahead of
this rework have already settled on.
Read next: OVOS Shell Related: GUI Protocol · GUI Service (legacy) · Screens on OVOS Today