UI — NiceGUI¶
NiceGUI entry point for Klea web interfaces.
This file is invoked directly to start the NiceGUI web interface.
It reads title / subtitle / server URL from sys.argv
and delegates to klea_utils.ui.web.nicegui.runner.run_nicegui_app().
Usage:
python app.py <title> <subtitle> <server_url> [--debug]
File: klea_utils/ui/web/nicegui/app.py
Copyright 2026 Ankur Sinha Author: Ankur Sinha <sanjay DOT ankur AT gmail DOT com>
NiceGUI runner for Klea web interfaces.
This module implements the main UI logic for the NiceGUI web interface, including the 3-column layout, chat functionality, and inspector panel.
File: klea_utils/ui/web/nicegui/runner.py
Copyright 2026 Ankur Sinha Author: Ankur Sinha <sanjay DOT ankur AT gmail DOT com>
- klea_utils.ui.web.nicegui.runner.run_nicegui_app(title: str, server_url: str, subtitle: str = '', disclaimer: str = '', footer_text: str = 'Powered by <a href="https://github.com/neuroml/klea">Klea</a>', debug: bool = False, nicegui_url: str = '0.0.0.0:7860', storage_secret: str = 'klea-nicegui-secret-change-me', app_name: str = 'klea-web') None[source]¶
Start the NiceGUI web server with the Klea chat interface.
This function is the main entry point for the NiceGUI frontend. It registers a
@ui.page("/")handler that builds the full UI viasetup_layout()and then starts the NiceGUI server.- Parameters:
title – Application title (displayed in the header and browser tab).
server_url – Base URL of the backend API server (e.g.
http://127.0.0.1:8005).subtitle – Optional smaller text shown next to title in the header.
disclaimer – Optional text shown below the chat input.
footer_text – HTML content for the footer bar.
debug – When
True, enable NiceGUI’s file-watch hot reload (reload=True). Set toFalsein production.nicegui_url –
host:portto bind the NiceGUI web server to (default:"0.0.0.0:7860").storage_secret – Secret used by NiceGUI for browser session persistence (default:
"klea-nicegui-secret-change-me").app_name – Log identity for this frontend process, used as the log file name so each app keeps its own logs (e.g.
"klea-rag-web").
- klea_utils.ui.web.nicegui.runner.setup_layout(chat_id: str, server_url: str, user_id: str = '', title: str = 'Klea', subtitle: str = '', disclaimer: str = '', footer_text: str = 'Powered by <a href="https://github.com/neuroml/klea">Klea</a>') None[source]¶
Build the full page UI: header, drawers, chat area, and footer.
User messages appear as right-aligned bubbles (grey background); system / bot messages are left-aligned, full-width and transparent, matching the Gemini/ChatGPT model without avatars.
Layout (left to right):
[left_drawer | center_column | right_drawer]
The left drawer uses Quasar’s mini mode to provide a ChatGPT-style rail that shows only icons when collapsed and full text when expanded.
- Parameters:
chat_id – Chat conversation identifier.
server_url – Base URL of the backend API server.
user_id – Opaque persistent user identifier.
title – Bold application title in the header bar.
subtitle – Optional smaller text shown next to title in the header.
disclaimer – Optional text shown below the chat input.
footer_text – HTML content for the footer bar.
Reusable custom NiceGUI widgets for Klea web interfaces.
File: klea_utils/ui/web/nicegui/widgets.py
Copyright 2026 Ankur Sinha Author: Ankur Sinha <sanjay DOT ankur AT gmail DOT com>
- class klea_utils.ui.web.nicegui.widgets.ChatBubble(text: str, stamp: str, is_user: bool, collapsed: bool, idx: int, on_expand=None, on_copy=None)[source]¶
Bases:
ElementA custom chat message bubble with built-in actions.
Replaces
ui.chat_messagewith full control over the layout. Each bubble has collapsible text content, a timestamp, a copy button, and an expand / collapse toggle – all flowing naturally inside the bubble (no CSS hacks).Usage inside a
@ui.refreshable:ChatBubble( text="Hello", stamp="12:00", is_user=True, collapsed=False, idx=0, on_expand=lambda: print("toggle"), on_copy=lambda: print("copy"), )
Server API client for the NiceGUI frontend.
All functions accept the server_url as their first argument so the caller can point them at any running Klea backend without shared state.
File: klea_utils/ui/web/nicegui/client.py
Copyright 2026 Ankur Sinha Author: Ankur Sinha <sanjay DOT ankur AT gmail DOT com>
- async klea_utils.ui.web.nicegui.client.clear_model_override(server_url: str, user_id: str, chat_id: str, role: str) bool[source]¶
DELETE the model override for a chat role.
- async klea_utils.ui.web.nicegui.client.create_chat_on_server(server_url: str, user_id: str, chat_id: str) None[source]¶
POST a new chat to the server so it persists.
- async klea_utils.ui.web.nicegui.client.delete_chat_on_server(server_url: str, user_id: str, chat_id: str) None[source]¶
DELETE the chat on the server.
- async klea_utils.ui.web.nicegui.client.hydrate_chats(server_url: str, user_id: str) None[source]¶
Fetch all chats and their messages from the server into the local state.
Populates the in-memory
chatsdict with every conversation belonging to user_id, including the full message history for each chat.After this call the frontend can switch between any chat without additional server round-trips. If the server has no data for this user yet the local store stays empty.
- async klea_utils.ui.web.nicegui.client.rename_chat_on_server(server_url: str, user_id: str, chat_id: str, title: str) None[source]¶
PATCH the chat title on the server.
- async klea_utils.ui.web.nicegui.client.set_model_override(server_url: str, user_id: str, chat_id: str, role: str, payload: dict) bool[source]¶
POST a model override for a chat role.
In-memory chat state for the NiceGUI frontend.
Keyed by {user_id}:{chat_id} so that colliding chat_ids across
different users do not interfere.
File: klea_utils/ui/web/nicegui/state.py
Copyright 2026 Ankur Sinha Author: Ankur Sinha <sanjay DOT ankur AT gmail DOT com>
- klea_utils.ui.web.nicegui.state.ensure_chat(user_id: str, chat_id: str) dict[source]¶
Return the chat session dict for user_id / chat_id, creating it if missing.
Each chat session dict has the following keys:
name Human-readable display name (auto-generated) created ``datetime.timestamp()`` of creation (float). pinned Whether the chat session is pinned to the top of the list. messages List of ``(text, stamp, is_user)`` tuples where *is_user* is ``True`` for user messages and ``False`` for bot / system messages. inspector_entries List of dicts with info/debug events for the most recent query in this chat session. inspector_expanded Set of indices into *inspector_entries* that are currently expanded in the UI. state_sections Dict of ``{node_label: section_data}`` for the status pane, ordered by first insertion (per node label). model_info Dict of active model config per role (from ``fetch_active_models``). token_usage Numeric token totals accumulated for this in-memory chat session.
- klea_utils.ui.web.nicegui.state.get_chats_sorted(user_id: str) list[tuple[str, dict]][source]¶
Return (chat_id, data) pairs for user_id, pinned first, then by creation desc.
Filters by the user_id prefix so that in a multi-browser scenario (same NiceGUI process) each user only sees their own chats.
Argparse parser for the Klea NiceGUI frontend entry point.
Provides a standard argparse parser for the arguments passed by
the Typer web command when it launches app.py. The entry point
simply calls make_parser().parse_args() and picks only the
arguments it needs.
Usage:
from klea_utils.ui.web.nicegui.parser import make_parser
args = make_parser("My frontend").parse_args()
run_app(
args.title, args.url,
subtitle=args.subtitle,
disclaimer=args.disclaimer,
debug=args.debug,
)
File: klea_utils/ui/web/nicegui/parser.py
Copyright 2026 Ankur Sinha Author: Ankur Sinha <sanjay DOT ankur AT gmail DOT com>
- klea_utils.ui.web.nicegui.parser.make_parser(description: str = 'Klea web interface') ArgumentParser[source]¶
Return a preconfigured
argparse.ArgumentParser.- Parameters:
description – Description shown in
--help.