# How nGPT UI Components Work Together: TUI Architecture Explained

> Discover how nGPT's UI components including tui, tables, colors, and formatters work together. Understand the TUI architecture of the nazdridoy/ngpt repository.

- Repository: [nazDridoy/ngpt](https://github.com/nazdridoy/ngpt)
- Tags: architecture
- Published: 2026-03-07

---

**nGPT's terminal interface is built from four specialized modules—[`colors.py`](https://github.com/nazdridoy/ngpt/blob/main/colors.py), [`tables.py`](https://github.com/nazdridoy/ngpt/blob/main/tables.py), [`formatters.py`](https://github.com/nazdridoy/ngpt/blob/main/formatters.py), and [`tui.py`](https://github.com/nazdridoy/ngpt/blob/main/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`](https://github.com/nazdridoy/ngpt/blob/main/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`](https://github.com/nazdridoy/ngpt/blob/main/interactive_ui.py), [`session_ui.py`](https://github.com/nazdridoy/ngpt/blob/main/session_ui.py), and [`tui.py`](https://github.com/nazdridoy/ngpt/blob/main/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`](https://github.com/nazdridoy/ngpt/blob/main/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`](https://github.com/nazdridoy/ngpt/blob/main/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`](https://github.com/nazdridoy/ngpt/blob/main/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`](https://github.com/nazdridoy/ngpt/blob/main/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`](https://github.com/nazdridoy/ngpt/blob/main/ngpt/cli/main.py) constructs the argument parser via [`ngpt/cli/args.py`](https://github.com/nazdridoy/ngpt/blob/main/ngpt/cli/args.py), it uses `ColoredHelpFormatter` from [`formatters.py`](https://github.com/nazdridoy/ngpt/blob/main/formatters.py). This immediately applies the color scheme defined in [`colors.py`](https://github.com/nazdridoy/ngpt/blob/main/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`](https://github.com/nazdridoy/ngpt/blob/main/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`](https://github.com/nazdridoy/ngpt/blob/main/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`](https://github.com/nazdridoy/ngpt/blob/main/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`](https://github.com/nazdridoy/ngpt/blob/main/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`](https://github.com/nazdridoy/ngpt/blob/main/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`](https://github.com/nazdridoy/ngpt/blob/main/tables.py) and [`colors.py`](https://github.com/nazdridoy/ngpt/blob/main/colors.py):

```python
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`](https://github.com/nazdridoy/ngpt/blob/main/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:

```python
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`](https://github.com/nazdridoy/ngpt/blob/main/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`](https://github.com/nazdridoy/ngpt/blob/main/tui.py):

```python
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`](https://github.com/nazdridoy/ngpt/blob/main/ngpt/ui/tui.py) (functions `create_multiline_editor` and `get_multiline_input`).

### Implementing Custom argparse Formatting

This example shows how the CLI integrates the coloured formatter:

```python
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`](https://github.com/nazdridoy/ngpt/blob/main/ngpt/cli/args.py) (lines 5‑15) – sets the formatter for the whole CLI.

## Key Files and Module Responsibilities

| File | Role | Direct link |
|------|------|-------------|
| [`ngpt/ui/colors.py`](https://github.com/nazdridoy/ngpt/blob/main/ngpt/ui/colors.py) | Detects ANSI support & stores colour codes. | [[`colors.py`](https://github.com/nazdridoy/ngpt/blob/main/colors.py)](https://github.com/nazdridoy/ngpt/blob/main/ngpt/ui/colors.py) |
| [`ngpt/ui/tables.py`](https://github.com/nazdridoy/ngpt/blob/main/ngpt/ui/tables.py) | Calculates terminal width and returns a dict for table sizing. | [[`tables.py`](https://github.com/nazdridoy/ngpt/blob/main/tables.py)](https://github.com/nazdridoy/ngpt/blob/main/ngpt/ui/tables.py) |
| [`ngpt/ui/formatters.py`](https://github.com/nazdridoy/ngpt/blob/main/ngpt/ui/formatters.py) | Custom `argparse` help formatter with colour handling. | [[`formatters.py`](https://github.com/nazdridoy/ngpt/blob/main/formatters.py)](https://github.com/nazdridoy/ngpt/blob/main/ngpt/ui/formatters.py) |
| [`ngpt/ui/tui.py`](https://github.com/nazdridoy/ngpt/blob/main/ngpt/ui/tui.py) | Low‑level UI helpers: multiline editor, clipboard, spinner, terminal input. | [[`tui.py`](https://github.com/nazdridoy/ngpt/blob/main/tui.py)](https://github.com/nazdridoy/ngpt/blob/main/ngpt/ui/tui.py) |
| [`ngpt/ui/interactive_ui.py`](https://github.com/nazdridoy/ngpt/blob/main/ngpt/ui/interactive_ui.py) | High‑level interactive session UI (help screen, welcome banner, conversation preview). | [[`interactive_ui.py`](https://github.com/nazdridoy/ngpt/blob/main/interactive_ui.py)](https://github.com/nazdridoy/ngpt/blob/main/ngpt/ui/interactive_ui.py) |
| [`ngpt/ui/session_ui.py`](https://github.com/nazdridoy/ngpt/blob/main/ngpt/ui/session_ui.py) | Session manager UI – prints session list, previews, and help tables. | [[`session_ui.py`](https://github.com/nazdridoy/ngpt/blob/main/session_ui.py)](https://github.com/nazdridoy/ngpt/blob/main/ngpt/ui/session_ui.py) |
| [`ngpt/cli/args.py`](https://github.com/nazdridoy/ngpt/blob/main/ngpt/cli/args.py) | CLI argument definition using the custom formatter. | [[`args.py`](https://github.com/nazdridoy/ngpt/blob/main/args.py)](https://github.com/nazdridoy/ngpt/blob/main/ngpt/cli/args.py) |

These files together implement the cohesive, colour‑aware terminal UI that nGPT provides.

## Summary

- **nGPT UI components** are organized into four specialized modules: [`colors.py`](https://github.com/nazdridoy/ngpt/blob/main/colors.py) for ANSI detection, [`tables.py`](https://github.com/nazdridoy/ngpt/blob/main/tables.py) for layout calculations, [`formatters.py`](https://github.com/nazdridoy/ngpt/blob/main/formatters.py) for CLI help styling, and [`tui.py`](https://github.com/nazdridoy/ngpt/blob/main/tui.py) for 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_COLOR` flag in [`colors.py`](https://github.com/nazdridoy/ngpt/blob/main/colors.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`](https://github.com/nazdridoy/ngpt/blob/main/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`](https://github.com/nazdridoy/ngpt/blob/main/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`](https://github.com/nazdridoy/ngpt/blob/main/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`](https://github.com/nazdridoy/ngpt/blob/main/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.