How nGPT UI Components Work Together: TUI Architecture Explained
nGPT's terminal interface is built from four specialized modules—colors.py, tables.py, formatters.py, and tui.py—that provide ANSI color detection, dynamic table sizing, custom argparse formatting, and low-level terminal helpers, respectively.
The nGPT project implements a cohesive terminal user interface (TUI) by composing small, focused UI components. Located in the ngpt/ui/ directory, these modules handle everything from color scheme detection to table layout calculations, ensuring consistent styling across interactive sessions, session management screens, and command-line help output.
The Four Core nGPT UI Components
Color Detection and Management (colors.py)
The ngpt/ui/colors.py module detects if the terminal supports ANSI colors and defines a COLORS dictionary containing the escape sequences. It exports a HAS_COLOR boolean flag that other modules check before applying formatting.
Every UI module—including interactive_ui.py, session_ui.py, and tui.py—imports COLORS and HAS_COLOR to color-code text, prompts, separators, and clipboard messages. When the terminal cannot render ANSI codes, COLORS entries become empty strings, causing the UI to degrade gracefully without garbled escape sequences.
Dynamic Table Sizing (tables.py)
The ngpt/ui/tables.py module calculates the terminal width and returns a consistent configuration dictionary for Rich tables. The primary function get_table_config(is_help_table=True|False) provides overall width and column widths for help tables versus data tables.
UI classes call get_table_config() to size tables that list commands, sessions, or any tabular data. For example, InteractiveUI uses is_help_table=True to determine a fixed width for the help table, while SessionUI uses is_help_table=False to get session_list_widths for displaying session metadata.
Custom CLI Formatters (formatters.py)
The ngpt/ui/formatters.py module supplies a custom argparse help formatter that colors option names, metavars, and sections while keeping alignment correct even with ANSI codes. The ColoredHelpFormatter class extends argparse.HelpFormatter to inject color sequences.
The command-line argument parser in ngpt/cli/args.py passes formatter_class=ColoredHelpFormatter. This gives the top-level CLI a colourful, wrapped help screen that matches the rest of the TUI, ensuring visual consistency from the first --help invocation through interactive mode.
Low-Level Terminal Utilities (tui.py)
The ngpt/ui/tui.py module provides low-level helpers that are not Rich-specific. It includes a multiline editor via prompt_toolkit, a cross-platform get_terminal_input function, a copy_to_clipboard helper, and a spinner animation.
Higher-level UI classes (InteractiveUI, SessionUI) call get_multiline_input(), copy_to_clipboard(), or spinner() to interact with the user without pulling in Rich. The module handles fallbacks gracefully—for example, if prompt_toolkit is unavailable, get_multiline_input falls back to a simple stdin loop.
How nGPT UI Components Interact During Runtime
The nGPT UI components follow a layered interaction flow that ensures consistent styling and behavior across different modes of operation.
1. Startup and CLI Initialization
When ngpt/cli/main.py constructs the argument parser via ngpt/cli/args.py, it uses ColoredHelpFormatter from formatters.py. This immediately applies the color scheme defined in colors.py to the help output, ensuring that option names appear cyan, metavars magenta, and section headers yellow.
2. Interactive Mode Initialization
When the user enters interactive mode, InteractiveUI is instantiated. In InteractiveUI.__init__, the class calls get_table_config(is_help_table=True) from tables.py to determine a fixed width for the help table. The help table is built with Rich (Table) using the width and column sizes returned.
All printed strings—including separators and prompts—are wrapped with COLORS[...] from colors.py. If HAS_COLOR is False, these become empty strings, preventing escape sequence pollution in piped output.
3. Session Management Display
SessionUI.print_session_list and SessionUI.print_help build Rich Table objects for displaying session metadata. Column widths (session_list_widths) come from tables.py with is_help_table=False. Row colours—including size indicators and selected row highlighting—use values from COLORS or per-session colour data.
4. Fallback and Non-Rich Interactions
When the user needs multiline text entry, InteractiveUI calls get_multiline_input() from tui.py. This function tries the prompt_toolkit editor first; if unavailable, it falls back to a simple stdin loop. Similarly, copy_to_clipboard() prints a coloured prompt using COLORS, reads a single-character answer via get_terminal_input(), and uses pyperclip when available.
5. Shared Colour Awareness
All UI components honour the HAS_COLOR flag from colors.py. This centralized color detection ensures that every module—whether formatting argparse help, rendering Rich tables, or printing spinner animations—degrades gracefully in monochrome terminals or when output is redirected to files.
Practical Code Examples
Building a Coloured Help Table
This example demonstrates how InteractiveUI constructs the help display using tables.py and colors.py:
from ngpt.ui.tables import get_table_config
from ngpt.ui.colors import COLORS
from rich.table import Table
from rich.console import Console
console = Console()
cfg = get_table_config(is_help_table=True) # ← tables.py
tbl = Table(show_header=False,
box=None,
padding=(0, 2),
width=cfg["table_width"])
# Columns – colourised via the formatter
tbl.add_column("Command", style="yellow", width=cfg["help_cmd_width"])
tbl.add_column("Description", style="white")
tbl.add_row(" /help ", "Show this help message")
tbl.add_row(" /exit ", "Quit the session")
# Print with a grey separator that respects terminal colour support
separator = f"{COLORS['gray']}{'─' * cfg['table_width']}{COLORS['reset']}"
console.print(tbl)
console.print(separator, style="dim")
Source:
ngpt/ui/interactive_ui.py(lines 26‑42) – builds the same table.
Displaying Session Lists with Dynamic Widths
This example shows how SessionUI renders session data using dynamic column configuration:
from ngpt.ui.tables import get_table_config
from rich.table import Table, box
from rich.console import Console
from rich.text import Text
cfg = get_table_config(is_help_table=False) # full width for data tables
console = Console()
table = Table(box=box.SIMPLE,
show_header=True,
width=cfg["table_width"])
w = cfg["session_list_widths"]
table.add_column("idx", style="cyan", width=w["idx"])
table.add_column("ID", style="cyan", width=w["id"])
table.add_column("Size", style="cyan", width=w["size"])
table.add_column("Session Name", style="cyan", width=w["name"], no_wrap=True)
table.add_column("Created", style="cyan", width=w["created"], no_wrap=True)
table.add_column("Last Modified", style="cyan", width=w["modified"], no_wrap=True)
# Example row
row = {
"idx": "0",
"id": "abc123",
"size": "••",
"name": "My Project",
"created": "23-10-01 10:00 AM",
"modified": "23-10-02 02:30 PM",
}
table.add_row(
Text(row["idx"], style="cyan bold"),
Text(row["id"], style="dim white"),
Text(row["size"], style="yellow"),
Text(row["name"], style="white bold"),
Text(row["created"], style="dim white"),
Text(row["modified"], style="dim white"),
)
console.print(table)
Source:
ngpt/ui/session_ui.py(lines 75‑120) – the method constructs the same layout.
Capturing Multiline Input with Fallback
This example demonstrates the low-level input handling from tui.py:
from ngpt.ui.tui import get_multiline_input
# Optional initial text (e.g., a previous draft)
initial = "def hello():\n print('Hello, world!')"
user_input = get_multiline_input(initial_text=initial)
if user_input:
print("You entered:\n", user_input)
else:
print("No input received.")
Source:
ngpt/ui/tui.py(functionscreate_multiline_editorandget_multiline_input).
Implementing Custom argparse Formatting
This example shows how the CLI integrates the coloured formatter:
import argparse
from ngpt.ui.formatters import ColoredHelpFormatter
parser = argparse.ArgumentParser(
description="nGPT – an AI‑powered terminal assistant",
formatter_class=ColoredHelpFormatter,
)
parser.add_argument("-m", "--model", help="Model name to use (default: gpt‑4)", default="gpt-4")
parser.add_argument("-t", "--temperature", type=float, help="Sampling temperature", default=0.7)
parser.print_help()
Running the script prints a help screen where option names are cyan, metavars magenta, and sections yellow, all while respecting terminal width.
Source:
ngpt/cli/args.py(lines 5‑15) – sets the formatter for the whole CLI.
Key Files and Module Responsibilities
These files together implement the cohesive, colour‑aware terminal UI that nGPT provides.
Summary
- nGPT UI components are organized into four specialized modules:
colors.pyfor ANSI detection,tables.pyfor layout calculations,formatters.pyfor CLI help styling, andtui.pyfor low-level terminal interactions. - The architecture follows a layered design where high-level UI classes (
InteractiveUI,SessionUI) consume services from low-level modules, ensuring consistent styling across argparse help, Rich tables, and plain-text prompts. - Graceful degradation is handled centrally through the
HAS_COLORflag incolors.py; when ANSI codes are unsupported, all UI components automatically emit plain text without escape sequence pollution. - Dynamic table sizing via
get_table_config()allows nGPT to adapt to terminal width changes while maintaining readable column proportions for both help screens and session lists.
Frequently Asked Questions
How does nGPT detect terminal color support?
The ngpt/ui/colors.py module attempts to detect ANSI color support by checking environment variables and terminal capabilities. It exports a HAS_COLOR boolean flag and a COLORS dictionary containing escape sequences. When the terminal cannot render colors (such as when piped to a file), COLORS entries become empty strings, allowing the UI to degrade gracefully without garbled output.
What happens if the terminal doesn't support ANSI colors?
All nGPT UI components honor the HAS_COLOR flag from colors.py. If color support is disabled, the COLORS dictionary returns empty strings for all color codes. This means InteractiveUI, SessionUI, and the argparse formatter all emit plain text without escape sequences, ensuring readable output in monochrome terminals or when redirecting to logs.
How are table column widths calculated in nGPT?
The ngpt/ui/tables.py module provides the get_table_config() function, which detects the current terminal width and returns a configuration dictionary. For help tables (is_help_table=True), it allocates specific widths for command and description columns. For session lists (is_help_table=False), it returns session_list_widths with proportions for idx, ID, size, name, created, and modified columns. This ensures tables adapt to terminal resizing while maintaining readability.
Can I use nGPT's UI components in my own project?
Yes, the UI modules in ngpt/ui/ are designed as reusable utilities. You can import ColoredHelpFormatter for custom argparse styling, use get_table_config() for Rich table layout management, or leverage get_multiline_input() from tui.py for cross-platform text entry. However, note that these components are optimized for nGPT's specific workflow, so you may need to adapt the COLORS dictionary or table width calculations to fit your application's requirements.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →