> ## Documentation Index
> Fetch the complete documentation index at: https://amd-gaia.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Terminal UI

> gaia-tui boots straight into the flagship GAIA agent's chat — a splash, a readiness gate that fixes what it can, then the conversation. No terminal required to leave.

`gaia-tui` is GAIA's terminal-native front door. It opens directly on the flagship
`gaia` agent — conversation, documents, data, web research, memory, skills — behind a
readiness gate that runs on every launch and checks the few things that would
otherwise make the agent fail. Where it can fix a problem itself, one key does it.
Where it can't, it says so and gives you the exact command.

Download the installer for your platform from **[amd-gaia.ai](https://amd-gaia.ai/#install)**,
run it, then open a new terminal:

```bash theme={null}
gaia-tui
```

> [!NOTE]
>
> The Terminal UI and the [Agent UI](https://amd-gaia.ai/docs/guides/agent-ui.md) are two front ends over the same
> agents. Use the terminal when you live in one or are on a headless box; use the Agent
> UI when you want rendered cards and a browser. Both take a dropped file or a pasted
> screenshot.

> [!NOTE]
>
> `gaia-tui` is the Go terminal binary — never `gaia`, which is the Python CLI's
> name and has entirely different subcommands. It accepts a leading `tui` word and
> drops it, so `gaia-tui` and `gaia-tui tui` open the same session. See the
> [CLI reference](https://amd-gaia.ai/docs/reference/cli.md#terminal-ui-gaia-tui) for its non-interactive
> subcommands.

> [!WARNING]
>
> This binary boots straight into the flagship, and it does not install, uninstall,
> search, or vote on agents — that stays the Python CLI's job (`gaia hub install email --trust` for the email agent).
> An earlier version of the TUI opened on an agent browser that did all of that,
> with the flagship listed as "Coming Soon." That screen, and the `list` / `install` /
> `uninstall` / `hub` subcommands that drove it, are gone for good.
>
> What did come back, scoped down: type `/agents` in chat to list every agent already
> installed on this machine and switch to one, without quitting the TUI. See
> [`/agents`](#3-chat) below.

## Installing

Every release publishes a native installer per platform at
[amd-gaia.ai](https://amd-gaia.ai/#install) (the page picks your platform). Each puts
two binaries on disk and on your PATH — `gaia-tui` (this app) and `gaia-agent` (the flagship agent
it runs) — so there is nothing to unzip and nothing to `chmod`.

| Platform | File | How to install | Installs to |
| - | - | - | - |
| Windows x64 | `gaia-<version>-win-x64-setup.exe` | double-click, tick **GAIA Terminal UI** | `%LOCALAPPDATA%\Programs\GAIA Terminal Hub` |
| macOS Apple silicon | `gaia-<version>-darwin-arm64.pkg` | double-click | `/usr/local/bin` |
| macOS Intel | `gaia-<version>-darwin-x64.pkg` | double-click | `/usr/local/bin` |
| Linux x64 (Debian/Ubuntu) | `gaia_<version>_amd64.deb` | `sudo dpkg -i gaia_<version>_amd64.deb` | `/usr/bin` |
| Linux x64 (Fedora/RHEL) | `gaia-<version>.x86_64.rpm` | `sudo rpm -i gaia-<version>.x86_64.rpm` | `/usr/bin` |

On Windows this is the one GAIA installer: on **Choose Components**, tick
**Terminal** — and the desktop app too, if you want both. [Install GAIA](https://amd-gaia.ai/docs/guides/install.md)
covers the choice and silent installs (`/S /COMPONENTS=tui`).

The Windows setup is per-user: it needs no administrator rights and shows no UAC
prompt. It also bundles Lemonade Server, so the install itself needs no network
(Lemonade downloads its own runtime the first time you run a model). Start Menu
and desktop shortcuts are created; open a **new** terminal afterwards, because an
already-open one keeps the PATH it started with. Quit GAIA before upgrading —
Windows cannot replace a running program, and the setup will tell you so rather
than install over it half-way.

The Windows setup also gives GAIA its own look in Windows Terminal. It adds a
**GAIA** profile (IBM Plex Mono, roomy spacing, a dark GAIA colour scheme) and installs
IBM Plex Mono for your account only. When Windows Terminal is installed, the shortcuts
open that profile. Without it, they run `gaia-tui` in the default console, and the
install log says so. Specifically, the setup writes:

| What | Where |
| - | - |
| The GAIA profile and colour scheme | `%LOCALAPPDATA%\Microsoft\Windows Terminal\Fragments\GAIA\gaia.json` |
| IBM Plex Mono Regular, Bold, Italic, Bold Italic | `%LOCALAPPDATA%\Microsoft\Windows\Fonts`, registered under `HKCU\Software\Microsoft\Windows NT\CurrentVersion\Fonts` |
| The font's licence (SIL OFL 1.1) | `IBM-Plex-Mono-OFL.txt` in the install folder |

Your Windows Terminal `settings.json` and default profile are never changed. To
restyle the profile, use Windows Terminal's settings. A reinstall rewrites the fragment
but keeps your overrides, because those live in `settings.json`. If IBM Plex Mono was
already installed, the setup leaves your copy alone. Uninstalling removes the
fragment and only the font files the setup itself added. If Windows Terminal has a
font open during uninstall, that face stays installed and the uninstall log says so.
To remove it, close Windows Terminal, then go to **Settings → Personalization → Fonts**.

> [!NOTE]
>
> There is no installer for Windows on Arm or Linux on Arm. The flagship agent
> publishes no build for either, so an installer there would set up the terminal app
> with no agent behind it. The raw `gaia-tui` binary is still published for all six targets
> if you want to run it against an agent you build yourself.

Uninstalling leaves `~/.gaia` — your chats, documents and memory — in place unless
you say otherwise. On Windows, the terminal is its own **GAIA Terminal UI** entry
in Installed apps, separate from the desktop app's, and its uninstaller offers to delete it; on Linux,
`apt remove` and `rpm -e` keep it. Lemonade Server is never removed with GAIA,
because other things may be using it — see `gaia uninstall --purge-lemonade`.

A macOS `.pkg` ships no uninstaller — that is the platform convention, not an
omission — so remove the files and then forget the receipt:

```bash theme={null}
sudo rm -f /usr/local/bin/gaia-tui /usr/local/bin/gaia-agent
sudo rm -rf /usr/local/share/doc/gaia-tui
sudo pkgutil --forget ai.amd.gaia.terminal-hub
sudo pkgutil --forget ai.amd.gaia.terminal-hub.docs
```

There are two receipts because the tools and the licence ship as separate
components — forget both. `pkgutil --forget` drops only the installation receipt
and deletes nothing, which is why the `rm` comes first. `~/.gaia` is untouched either way.

macOS packages are unsigned unless the release was built with Apple credentials
configured. Unsigned, Gatekeeper warns that the package comes from an
unidentified developer. Right-click → Open no longer bypasses that as of macOS 15:
dismiss the warning, then go to **System Settings → Privacy & Security** and click
**Open Anyway** next to the blocked package.

### Building from source

Contributors who want the binary from a checkout, rather than the installer:

```bash theme={null}
cd tui && make build     # -> tui/bin/gaia-tui
```

This builds `gaia-tui` only. `gaia-agent` still has to come from an installer or a
hub download — the readiness gate below says so on the first screen if it is
missing.

## The boot sequence

Every launch — `gaia-tui` with no arguments, or `gaia-tui run email` — goes
through the same screens: a splash, a readiness gate, then chat. The flagship
agent adds a short "Getting GAIA ready" stage before chat opens — see
[Getting ready](#getting-ready).

```bash theme={null}
gaia-tui                 # the flagship agent
gaia-tui run email       # any other agent, by id
```

### 1. Splash

The first frame is GAIA's mascot over the wordmark and tagline, while the readiness
gate spins up behind it — the launch never opens on a blank terminal:

```
  [ GAIA mascot ]

  G A I A    Your local AI agent — by AMD

  starting GAIA…
```

On a terminal shorter than 32 rows or narrower than about 44 columns, the mascot
is dropped and the frame is just the wordmark and tagline on one line.

### 2. The readiness gate

For the flagship, three things are checked, in order, each depending on the one
before it: is `gaia-agent` on this machine, is the local model server (Lemonade)
reachable, and do the models **load**. The gate stops at the first failure — a
missing model server makes "do the models load" meaningless.

An all-green machine lands in chat without a keypress, naming the chat model on
its way out. Because the last check loads the models, that takes a few seconds
when they are already in memory and longer right after a reboot — time the first
message would otherwise have spent.

#### First run

On a new machine nothing is broken yet — Lemonade and the models just are not
there. The gate shows that as numbered steps, not failures, and the first step
is a question: where should chat run? It comes before any download, because the
answer decides what gets downloaded.

```
  Setting up GAIA                                                    step 1 of 3
  ──────────────────────────────────────────────────────────────────────────────
  Step 1 of 3 — where should chat run?
  Change it any time: p on this screen, /provider in chat.

  > 1. Local
       Private and free: nothing leaves this PC. Speed depends on this PC.
       Downloads ~6 GB of models. Setup picks the model that fits this PC's
       memory.

    2. Fireworks AI
       Fast on any PC. Conversations are sent to Fireworks AI, and usage is
       billed to your key.
       Needs a Fireworks AI API key. Downloads under 1 GB.

    3. AMD LLM Gateway
       Fast on any PC. Conversations are sent to your organisation's AMD LLM
       Gateway.
       Needs your gateway key (and its URL). Downloads under 1 GB.

  ──────────────────────────────────────────────────────────────────────────────
  ↑/↓ move · p all providers · enter choose · esc back to the steps
```

Move with `↑`/`↓` (or press `1`–`3`) and press `Enter`. When Lemonade is already
installed, the Local option names the model setup would download and whether it
fits this PC's memory, by the same rule the provider panel uses. `esc` goes back
to the list of steps, where the question is step 1 and `Enter` reopens it. If you
chose a model on an earlier launch, or started with `--model` or
`--use-claude`, the question is skipped.

Every choice still installs Lemonade next: it runs local models, and for a cloud
provider it routes the requests and computes the embeddings that document
search and memory use.

* **Local** — step 2 installs Lemonade, step 3 downloads the models.
* **Fireworks AI** or **AMD LLM Gateway** — step 2 installs Lemonade. Step 3
  opens that provider's key form; paste the key, pick a model, and setup
  downloads only the embedding model. No local chat model is downloaded.

When the AMD gateway can't be reached (no AMD network or VPN), its option is
greyed out and says "No network available". Connect, then press **r**.

```
  Setting up GAIA                                                    step 2 of 3
  ──────────────────────────────────────────────────────────────────────────────
    [ok]  GAIA agent          C:\Users\you\.gaia\bin\gaia-agent.exe
  > [ ]   Lemonade            Step 2 of 3 — install the local model server (~1 min)
          Lemonade runs AI models on this machine and routes chat to the
          provider you pick. Setup installs it privately for GAIA — nothing
          system-wide.
          enter start step 2
    [ ]   Language model      Step 3 of 3 — download the models (~6 GB)
  ──────────────────────────────────────────────────────────────────────────────
  enter start step 2 · p AI provider · r re-check · d details · esc back
```

Press `Enter` and the step runs right there. The row it is working on shows it,
and the line underneath says what is happening in words — never a log line.
The Lemonade step installs Lemonade and stops, downloading nothing — and so does
every retry of it, and the key on a Lemonade row that is installed but not
running. `p` still opens the full provider panel at any point, to pick a
specific model rather than the default. Press `Enter` again to start the last
step:

```
  Setting up GAIA                                                    step 3 of 3
  ──────────────────────────────────────────────────────────────────────────────
    [ok]  GAIA agent          C:\Users\you\.gaia\bin\gaia-agent.exe
    [ok]  Lemonade            running at http://localhost:13305/api/v1
    [..]  Language model      ⣟  downloading Gemma-4-E4B-it-GGUF…

  ⣟  Step 3 of 3 — downloading Gemma-4-E4B-it-GGUF · 0:05
  Leaving this screen stops setup.
  ──────────────────────────────────────────────────────────────────────────────
  r re-check · d details · esc back
```

`esc` cancels it. If setup stops, the screen says why and `d` shows its full
output; `gaia init` does the same work from a terminal.

If this PC already runs a Lemonade Server (v10.9.0 or newer) on its default
port, the Lemonade row offers it instead of step 1: press `f` to use it, or `g`
to install GAIA's own (saved once GAIA's server is installed and running). Using yours keeps one server and one copy of each model
on the PC. A server that needs an API key shows the `gaia lemonade connect`
command that saves the key. The choice is remembered. GAIA never changes your
server's setup: it doesn't register cloud providers or hand it keys, and the
`/provider` panel uses a provider only if your server already has it. Setup
downloads only the models your server lacks. To switch
back, run `gaia config set lemonade_mode gaia` (it's refused until GAIA's own
server is installed; `gaia init --gaia-lemonade` does both). See
[Use a Lemonade you already run](https://amd-gaia.ai/docs/guides/install.md#use-a-lemonade-you-already-run).

When setup finishes, the gate checks the models by **loading** them once — the
chat model, and the embedding model that document search and memory use — and
only then says it is ready, naming the chat model and its size:

```
  Setup finished and the models load. Chat runs on Gemma-4-E4B-it-GGUF (5.6 GB,
  on this machine). Press enter to start GAIA.
```

#### When something is actually broken

A real failure is marked `[!]` and says what to do. For example, a model that
downloaded but will not load:

```
  > [!]   Language model      user.embeddinggemma-300m-GGUF will not load
          It is downloaded, but the model server could not start it, so
          document search and memory will not work. Chat still does.
          Stop GAIA's model server, then press r — it starts again with
          current settings. If it still fails, attach the output of
          `gaia diagnostics` to a bug report.
          run:    gaia lemonade embedded stop
          look:   https://github.com/amd/gaia/issues
```

An embedding model that will not load does not stop the launch — `Enter` starts
GAIA without document search and memory. A chat model that will not load does.

If `gaia-agent` itself is missing, the gate stops on the first row and sends you
to the installer — there is no in-TUI download for the agent binary:

```
  Setting up GAIA                                                   0 of 3 ready
  ──────────────────────────────────────────────────────────────────────────────
  > [!]   GAIA agent          not on this machine
          gaia-agent is the program that does the thinking. Nothing runs without it.
          Re-run the GAIA installer — it ships gaia-agent alongside gaia-tui.
          run:   https://amd-gaia.ai/#install
          look:  https://amd-gaia.ai/docs/guides/gaia
    [ ]   Lemonade            —  checked once "GAIA agent" is fixed
    [ ]   Language model      —  checked once "GAIA agent" is fixed
  ──────────────────────────────────────────────────────────────────────────────
  r re-check · d details · esc back
```

This row has no `f`: the TUI cannot install its own agent binary, so it names
the installer instead of offering a key that would not work.

A daemon-supervised sidecar agent goes through the same three screens, but its
gate has more rows: background service, sidecar, Lemonade, and model. The
flagship is one of these once `gaia init` has installed it.

If the background service does not list the agent at all, the sidecar row names
`gaia daemon restart`. The service reads its agent list only when it starts, so
one started by an older GAIA does not see an agent installed since — the remedy
also names the install command (`gaia init` for the flagship) in case it is missing.

When the background service or the agent is simply not running — the usual
state after a reboot — the gate starts it itself and shows `starting…` on that
row, so the launch needs no keypress. A start that fails keeps the row's error
and remedy, and `f` tries again. The gate starts nothing on its own when the
service's port answers as something else, or when `LEMONADE_BASE_URL` points at
another machine; those rows wait for `f`.

#### Markers

| Marker | Meaning |
| - | - |
| `[ok]` | Checked and working |
| `[!]` | Checked and failed |
| `[?]` | Tried, but couldn't establish an answer either way — not a pass |
| `[ ]` | Not checked yet (waiting on the row above), or a first-run step setup has not done yet |
| `[..]` | Checking now, or setup is working on this row |

The marker and the words carry the state on their own, so the screen reads the same
on a monochrome terminal or piped to a file.

#### Keys

| Key | What it does |
| - | - |
| `f` | Apply the focused row's fix — shown only when that row has one (e.g. downloading the models) |
| `r` | Re-check everything |
| `d` | Toggle the raw answer the check got — paste this into a bug report |
| `↑` / `↓` (or `k` / `j`) | Move between rows |
| `Enter` | On a first-run step, start it. Otherwise continue anyway — offered only when nothing is outright broken |
| `Esc` | **Quit.** There is no screen behind the gate to go back to — the footer still shows this key as "back" |
| `Ctrl+C` | Quit |

`Enter` is not offered while a row is failing outright. Press it anyway and the
screen names the blocker rather than starting a chat that cannot talk. It *is*
offered when a row is merely unverified (`[?]`) — nothing there says anything is
broken.

### Getting ready

On a local model, the flagship's first answer used to pay for starting the
agent, loading the model and reading its \~10K-token instructions while you
watched a spinner. That now happens before the chat opens, with each step
named:

```
  Getting GAIA ready

  ✓ Starting the agent
  ✓ Tidying memory
  ✓ Indexing tools
  ⣾ Loading Gemma-4-E4B-it-GGUF and reading its instructions  0:05

  This happens once per session, so your first answer starts right away.
  Type now — it's sent the moment GAIA is ready · Esc to show the chat
```

Anything you type meanwhile waits and is sent the moment GAIA is ready. `Esc`
shows the chat without stopping the warm-up. A remote model (Fireworks, the AMD
gateway, Claude) has nothing to load, so the stage ends as soon as the agent
has started. A launch with `--query` skips it, because the question pays for
the same work.

### 3. Chat

Once the gate clears, GAIA starts the agent and drops you into the conversation:

```
GAIA │ agent gaia v0.2.0 │ Gemma-4-E4B-it-GGUF
────────────────────────────────────────────────────────────────────────────────
Welcome to GAIA
Connected to: agent gaia v0.2.0 (GAIA core 0.25.0)

Type a message and press Enter to start chatting.
Type /help for available commands.
────────────────────────────────────────────────────────────────────────────────
┃ Ask anything... (Enter to send, Ctrl+C to quit)
  ● agent gaia v0.2.0 connected                                     Ctrl+C quit
```

The `agent <id>` segment is always the stable id, lowercased — the same string
`--agent <id>` takes, so you can read it straight off the header and pass it back.
The version beside it is the one the running agent reports about itself, and the
welcome line adds the GAIA core it runs on. An agent too old to report a
version gets no number at all rather than one read from an install record, which
can name a different build than the one answering.
On a narrow terminal this segment is the first thing to give way, never the model
chip next to it.

The model chip names the chat model from the moment the chat opens, local
included: the one the startup check loaded, until the agent reports the model it
actually runs. The model you last picked is restored on the next launch; if it
can't be, the chat says so in one line and opens the provider picker. See
[Your model is remembered](https://amd-gaia.ai/docs/guides/ai-providers.md#your-model-is-remembered).

Once setup has installed the flagship as a hub package, the TUI reaches it through
the background service. `/model` and `/provider` work the same there: the switch
is checked against the models Lemonade serves, the header names the new model, and
your next message runs on it. It is remembered once that message completes; if the
agent refuses the model, the previous one comes back. Neither command is ever sent
to the agent as a question. An agent too old to switch models mid-chat says so and
names the update command.

| Key | What it does |
| - | - |
| `Enter` | Send message. Mid-answer it goes to the turn already running — see below |
| `Alt+Enter`, `Ctrl+J` | New line in the composer |
| `Ctrl+Backspace`, `Alt+Backspace`, `Ctrl+W` | Delete the word before the cursor. A terminal that sends `^H` for plain Backspace (PuTTY's "Control-H" setting, `stty erase ^H`) deletes a word with Backspace too; set it to send `DEL` |
| `Ctrl+Delete`, `Alt+Delete`, `Alt+D` | Delete the word after the cursor |
| `Esc` | Idle: clear the composer. Streaming: stop the turn; the agent keeps its session. Press again to stop at once — an agent the TUI runs itself is then restarted without its loaded skills or grants |
| `Ctrl+C` | Quit |
| `Shift+Tab` | Change the permission mode: ask → accept edits → full access — see [When the agent asks first](#when-the-agent-asks-first) |
| `↑` / `↓`, `PgUp` / `PgDn` | Scroll the conversation one line / one page |
| `Home` / `End` | Jump to the top / bottom, if the composer is empty |
| Drag and drop a file or folder | Its path lands in the composer, quoted by your terminal if it has spaces |
| `Ctrl+V` | Paste — text, or a clipboard **image** (a screenshot), which is saved to a temp file and its path inserted |
| `Ctrl+Y` | Copy the whole answer |
| `Ctrl+B` | Copy the last code block in the answer |
| `Ctrl+O` | Show every step in full — the agent's narration, wrapped commands, timings — or fold it back to one row per step |

### Reading a turn

While the agent works, and afterwards, each thing it did is one short row, with
the answer set apart below:

```
  ▪ Reading file: toybox/dates.py
    └ 3 symbols
  ▪ Editing file: toybox/dates.py x2 · approved
  ▪ Running command: python -m pytest -q tests/
    └ exit 0 · 2 lines

  Fixed and verified — all 4 tests pass.
```

* **Paths** are shown relative to the folder you started GAIA in, or under `~`;
  a path that is still long keeps its end.
* **A failed step** keeps its reason under it, remedy included — that row is
  where a failure lives, so a retried call is one red row, not a separate error.
* **A confirmation** asks once, in the prompt pinned above the composer. The step
  it gated then records your answer in a word: `approved`, `denied`, or `always
  allowed '<scope>'`.
* **The agent's narration** ("Let me check the tests first") is folded away.
  `Ctrl+O` shows it, along with each step's full command and timing. A stage or a
  narration line the agent repeats word for word — a plan's "Following the plan
  to …" headline before every step — is shown once, until it changes.

### Saying something while the agent is still working

You can keep typing through an answer — the composer stays live while text
streams and while tools run. Press `Enter` and the message goes to the turn
*already running*: the agent picks it up at its next step and answers it
alongside what it was doing, instead of you waiting out a five-minute task to
ask a one-line follow-up. Nothing is interrupted and no second turn starts.

The row under the composer says which of two things `Enter` will do, because
they are not the same:

| Row | Meaning |
| - | - |
| `⏎ sends to the running turn` | The agent takes it now |
| `⏎ queues` | It goes out when this turn ends — a slash command, or an agent too old for mid-turn input |
| `⏎ sending · …` | In flight; it appears in the conversation once the agent has it |

Your message only enters the transcript once the agent actually received it. If
delivery fails you are told why, and the text goes back to the queue (or to the
composer, if the turn has already ended) rather than disappearing.

Mid-turn messages need agent contract 2.15 or newer. On an older one `Enter`
queues as before, and the TUI says so with the command to update.

By default the mouse belongs to your terminal, so you drag to select text and
copy and paste with your terminal's own keys (`Ctrl+Shift+C` / `Ctrl+Shift+V`,
`Cmd+C` / `Cmd+V`, or right-click). The wheel still scrolls the conversation:
GAIA turns on your terminal's alternate scroll mode, which sends each wheel tick
as `↑` / `↓`. Your terminal's selection only covers what is on screen, though:
dragging past the top or bottom of the conversation doesn't scroll it. To select
something longer, press `Ctrl+T` to hand the mouse to GAIA, or copy without the
mouse at all with `Ctrl+Y`, `/copy` or `/copy all`. The status bar shows the
`Ctrl+T` hint either way.

| Mouse | What it does |
| - | - |
| Wheel | Scrolls the conversation |
| Drag | Selects text, for your terminal's own copy |
| `Ctrl+T` | Hands the mouse to GAIA (the rows below). `Ctrl+T` again gives it back to your terminal |
| Drag, after `Ctrl+T` | Selects inside GAIA. Drag past the top or bottom edge and the conversation scrolls, extending the selection. Releasing copies it as plain text: no `▶ You:` label, padding, borders or timings, and a message selected end to end is copied as its original markdown, so code blocks come out exactly. `Enter` copies it again, `Esc` clears it |
| `Shift`+click, after `Ctrl+T` | Extends the selection to the click and copies it, in terminals that pass `Shift`+click to the app. Some, Windows Terminal among them, keep it for their own selection instead |
| Click / double-click, after `Ctrl+T` | A printed `http(s)` link opens in your browser; a double-click copies the whole message. Printed links are also real terminal hyperlinks, so terminals that support them (iTerm2, WezTerm, kitty, Windows Terminal, GNOME Terminal, foot, recent Alacritty) open them with their own gesture either way |
| Hover / click, on a `/` palette row or a question's options | Hover (or click) selects the row; clicking the already-selected row runs or answers it, same as `Enter`. Click outside the palette to close it. The palette takes the mouse only while it is open |

| Command | What it does |
| - | - |
| `/help` | Show the shortcut overlay (scrolls with `↑`/`↓`/`PgUp`/`PgDn` if it doesn't fit) |
| `/clear` | Clear the conversation |
| `/setup` | Re-run first-time setup (`gaia init`) for the flagship agent |
| `/memory` | See what the agent has stored about you — read-only, `Esc` to dismiss |
| `/model` | Switch the flagship agent's live model. Bare `/model` lists what you can switch to |
| `/provider` | Choose where chat runs — Local, Fireworks AI, or the AMD LLM Gateway — and set its key. See [AI providers](https://amd-gaia.ai/docs/guides/ai-providers.md) |
| `/gateway` | Connect the AMD LLM Gateway and pick which of its models GAIA uses. See [LLM gateway](https://amd-gaia.ai/docs/guides/llm-gateway.md) |
| `/slack` | Connect this agent to Slack, or show the connection's status. See [Slack](https://amd-gaia.ai/docs/guides/slack.md) |
| `/full-access` | Explain full access; `/full-access confirm` then turns it on for this session (off by default) |
| `/full-access off` | Turn full access off for this session |
| `/full-access always` | Keep it on for every future session (writes `full_access` to `~/.gaia/config.json`) |
| `/full-access never` | Stop it coming back on future launches |
| `/cost` | What this session has spent — time, steps, tool calls, tokens, dollars |
| `/cost help` | Where the rates come from, and how to set your own |
| `/copy` | Pick any message with `↑` / `↓` and copy it with `Enter` (`Esc` cancels) |
| `/copy all` | Copy the whole conversation as markdown |
| `/agents` | List agents installed on this machine and switch to one, without quitting |

Commands the current agent can't run drop out of `/help` and the `/` palette on
their own — `/model`, `/setup`, and `/provider` are flagship-only, and `/memory`
needs a peer new enough to serve it (see the [memory guide](https://amd-gaia.ai/docs/guides/memory.md#terminal-ui-memory)).
`/agents` is always available.

Selecting a different agent from `/agents` reconnects in place and re-runs the
readiness gate for it; the transcript stays on screen with a divider noting the
switch, but the new agent never sees the conversation above that line. Backing
out of the picker (`Esc`) returns to the chat you were already in — it does not
quit the TUI.

Typing `/` as the first character of an empty composer opens a palette listing every
command above with a one-line description, so there's no need to already know them or
open `/help` first:

```
         ╭────────────────────────────────────────────────────────────╮
         │  Slash Commands                                            │
         │  ────────────────────────────────────────────────────────  │
         │  /mo▏                                                      │
         │                                                            │
         │  ▸ /model   Switch the model this session runs on (gaia …  │
         ╰────────────────────────────────────────────────────────────╯
```

Keep typing to narrow the list (`/mo` above narrows to `/model`), `↑`/`↓` to move the
selection, `Enter` to run it, `Esc` to close the palette without touching the composer
or cancelling a running turn. A `/` typed mid-sentence is just a slash — the palette
only opens on an otherwise-empty line.

The mouse works the same list: hovering a row moves the selection there, and
clicking the row that is already selected runs it — the common case, since hovering
already selects before you click. Clicking outside the box closes the palette, same
as `Esc`. None of this needs a mouse: every path above is reachable from the keyboard
alone.

When an agent asks a follow-up question mid-turn — "Gmail or Outlook?", say — its
options are the same: `↑`/`↓` (or `Tab`) to move between them, a number key to pick
one directly, `Enter` to answer, and the mouse works identically to the palette above.
`Esc` cancels the turn rather than the question, since abandoning it is the only way
out once it is up.

### When the agent asks first

Before the agent runs a shell command or Python, or writes a file, it asks. The
prompt shows the command once, labelled by what it does:

```
 RUNS CODE  Run this command?
 python -m pytest -q tests/ 2>&1
 in ~/AppData/…/newuser/proj
 Can run any code, with your permissions.
 mode: ask · shift+tab to change · expires in 10 minutes
 y once · a always: pytest (this session) · n/esc deny
```

| Label | Means |
| - | - |
| `READ` | Only looks — `ls`, `git status`, `gh issue list` |
| `WRITE` | Creates or changes files or repository state — `mkdir`, `git commit`, a file edit |
| `RUNS CODE` | Runs code GAIA can't see into — tests, scripts, a program it doesn't know |
| `DESTRUCTIVE` | Deletes or discards, and may not be reversible — `rm`, `git reset --hard`, `git push --force` |

Paths are shown relative to the folder you started GAIA in, a leading `cd` moves
to its own `in …` line, and a long command keeps its start and its end with the
middle marked as cut. The `in …` line also appears when an earlier `cd` left the
session in another folder. A `WRITE` or `RUNS CODE` command gets one plain line
saying what it can do.

A command GAIA doesn't run unasked — `python script.py`, `git commit`, `npm test`
with no skill loaded for it — gets this prompt rather than an error. `a` covers
that one command family (`git commit`, `python (any script)`) for the session and
nothing wider. If you deny it, the agent is told not to get the same result
another way, and stops to explain.

A command GAIA's own checks don't cover — `git push`, `git fetch`, Python passed
with `-c`, a PowerShell command it can't read, a line with `$(…)`, a path outside
the project — is asked about too, with three differences. The prompt shows the
exact line the shell will run, unshortened, and the full folder it runs in. A
risk line says what it can do: "Sends your commits to the remote repository.",
"Reads or changes files outside this project: …", or "Can run any code with your
permissions — GAIA can't inspect this command." And only `y` and `n` are offered:
approving runs that exact line once, and the next one asks again.

```
 WRITE  Run this command?
 git push
 in ~/work/proj
 Sends your commits to the remote repository.
 y once · n/esc deny
```

A few stay refused with no prompt: a PowerShell `-EncodedCommand` or a line
with invisible or line-break characters (the prompt couldn't show what runs), a
line whose quoting GAIA can't split the way the shell would, a line its checks
don't cover that also deletes or discards work (`git push --force`, `git reset --hard`, `git clean`, `rm` outside the project), and folders no approval can
open (credential folders, the system temp folder, a whole drive or your home
folder). The agent
says what it would have run, so you can run it yourself.

| Key | What it does |
| - | - |
| `y` | Run it this once |
| `a` | Run it, and stop asking about that kind of command for the rest of the session. The prompt names exactly what `a` covers: `pytest (runs the test code it finds)` covers every spelling of a test run (`python -m pytest`, `cd proj && pytest 2>&1 \| tail`), never a different program. A command that runs code it does not show says so — `make (runs the Makefile's commands)`, `pip install (runs the package's setup code)`, `python -m explore (runs that Python module)` — and `python (any script)` and `Python snippets (run_python)` cover any Python code. Anything that runs code from the agent's own scratch folder never offers `a`: a script there, a shell command run there or naming a path there, or a script handed one. Writing there never asks, so each run is answered on its own. Deletes never offer `a` |
| `n` / `Esc` | Don't run it. The agent is told you said no |

A prompt nobody answers expires after 10 minutes. The agent is told it **timed
out**, not that you refused, so it asks whether you still want it rather than
giving up on something you never saw.

#### Permission modes

`Shift+Tab` cycles the mode, and the status bar always shows which one is on:

| Mode | What asks first |
| - | - |
| `ask` (default) | Every shell command, Python run and file write |
| `accept edits` | Shell commands and Python still ask. File edits inside the folder you started GAIA in run without asking. Hidden files and folders (`.git/`, `.bashrc`, `.github/`), folders on your `PATH`, and a file that would stand in for a real program on Windows (`git.bat`) still ask. Started from your home folder or a drive root, nothing is auto-accepted |
| `full access` | Nothing — see below |

Full access is never switched on by a stray keypress. The first time `Shift+Tab`
reaches it in a session, GAIA explains what it does and stays in `ask`; type
`/full-access confirm` to turn it on. After that, or in a session launched with
`--full-access` or with `full_access` saved in your config, `Shift+Tab` switches
straight to it. Turning it off is never gated. While it is on, a banner says so
on every frame.

Commands GAIA's checks don't cover — printing a credential (`gh auth token`), a
`git` option that hides a script — ask once in `ask` and `accept edits`, showing
the exact line, and no `a` answer covers them. An encoded PowerShell command, or
one that deletes or discards work on such a line, stays refused. Only full
access lifts the shell guardrails; see [Full access](https://amd-gaia.ai/docs/reference/cli.md#full-access).

A session launched with `--use-claude` skips first-boot setup entirely and does not
start the local server — that flag exists to avoid the local backend, so running an
installer that launches it would defeat it, and would hold the first answer behind a
multi-minute install. The transcript says the server was not started and names what
still needs it: RAG, memory and the code index embed through Lemonade, which has no
Claude equivalent. Run `gaia init --skip-chat-model`, or `/setup` in
the composer, when you want those.

## What a session costs

`/cost` answers "what has this conversation spent", which is the question behind
deciding whether a task is worth running on a cloud model at all:

```
Session so far — 12 turns on fireworks.glm-5p3

  active time   14m 22s
  agent steps   84
  tool calls    132

  input tokens  1.2M   (969.7k served from cache, 77%)
  output tokens 93.0k

  cost          $1.4083 USD  (input $0.3921 + cached $0.2521 + output $0.4092)
                published rates as of 2026-09-13
```

Two things that line is careful about, because a cost readout that gets them wrong
looks like a measurement and nobody re-checks it:

* **Every number is measured, never estimated.** They are summed from what the
  backend reported for each turn. A turn whose backend reported no token counts
  still counts as a turn, contributes nothing to the token totals, and the view
  says how many turns went unmeasured rather than quietly averaging over them.
* **`active time` is the sum of the turns, not the clock.** The minutes you spend
  reading an answer are not the agent working, so they are not in it.

While a **metered** model is running — a cloud provider you are billed by, or Claude
— the running spend also rides the status bar, so it is in front of you when you
decide whether to ask the expensive follow-up. A local model costs nothing to run
again and a gateway your organisation already pays for is not your bill, so neither
shows the line.

### Rates, and setting your own

Rates for the models GAIA ships are built in, and every dollar figure is printed with
the date they were read, so a stale card is visible rather than silent. A model with
no published rate shows tokens and no dollars — an absent figure sends you to look it
up, where a guessed one quietly prices your month wrong.

To override one — a negotiated price, a tier that isn't listed, or a correction after
a provider moves its prices — write `~/.gaia/model-prices.json`:

```json theme={null}
{
  "fireworks.glm-5p3": {
    "input_per_mtok": 1.40,
    "output_per_mtok": 4.40,
    "cached_per_mtok": 0.26
  }
}
```

Dollars per million tokens; your file wins over the built-in rates, and the readout
says which of the two it quoted. Keys match exactly first and then by longest prefix,
so one entry can cover a whole family. Omitting `cached_per_mtok` bills cached input
at the full input rate, and setting it to `0` means cached input is free — different
offers, so they are written differently. `GAIA_MODEL_PRICES` overrides the path.

If that file exists but can't be parsed, `/cost` says so and names the problem rather
than reporting "no rate configured" — otherwise you would edit a file that is already
being ignored.

To run a turn somewhere other than this machine — Fireworks AI or your
organisation's AMD LLM Gateway — choose it at the first-run question, press **p**
at the readiness gate, or type `/provider`. See [AI providers](https://amd-gaia.ai/docs/guides/ai-providers.md).

## When GAIA asks permission

Some tools do things that are hard to undo. Those stop and ask:

```
RUNS CODE  Run this command?

 <the command the agent wants to run>

 mode: … · expires in …

 y once · a always: <command> (this session) · n/esc deny
```

The first line is a risk badge — `READ`, `WRITE`, `RUNS CODE` or
`DESTRUCTIVE` — and the question. Tools GAIA knows get a plain question (`Run
this command?`, `Write this file?`, `Install this skill?`); any other tool reads
`Allow <tool>?`. A `DESTRUCTIVE` prompt adds a warning line under the call.

**y** runs it once, **n** or **esc** denies. Denying is a normal outcome, not an
error — the agent is told you said no, doesn't try another way to do the same
thing, and carries on with whatever doesn't need it. When nobody can answer — a
scheduled or background run, or a prompt that expires — the command doesn't run.
A command GAIA's own checks don't cover offers no `a`: it shows the exact line
and a risk line, and runs once if you say yes (see
[When the agent asks first](#when-the-agent-asks-first)).

The prompt names the tool *and its arguments*, because the argument is usually
the part that matters. An "always allow" answer, where offered, is scoped to
that specific call — approving `gh issue list` once does not hand over your
shell for the session.

`--bypass-permissions` runs every tool without asking, and the TUI shows a
persistent warning the whole time it is on. `/bypass off` turns it off
mid-session.

## Running another agent

The flagship is the default, but `gaia-tui` can also drive `email` by id — it keeps
its own five-row readiness gate:

```bash theme={null}
gaia-tui run email
gaia-tui run email --query "triage my inbox"   # one-shot: answer on stdout
gaia-tui chat --agent email                    # same thing, via `chat`
```

Installing or removing it is the Python CLI's job:

```bash theme={null}
gaia hub list
gaia hub install email --trust
gaia hub uninstall email
```

## Colours (light vs dark terminals)

Colours adapt to your terminal automatically. Some terminals never answer that
query (SSH, tmux, a CI log) — if the screen comes out hard to read, force a mode:

```bash theme={null}
GAIA_TUI_THEME=light gaia-tui    # or dark; unset or "auto" = detect
```

## Troubleshooting

**"not downloaded yet" when a chat model already works.** The **Language
model** row covers the embedding model too, and the embedder is what usually
blocks a machine that can already chat. The row says "Several GB" because that
is the common case; if chat works, the missing piece is the \~300 MB
`user.embeddinggemma-300m-GGUF`. `gaia init --check` names the exact model id,
and **f** fetches just what is missing.

**The gate says Lemonade is fine but chat fails.** The gate checks that the
server answers; it does not load a model. Check the server's own log —
`~/.gaia/lemonade/lemond.log` for the embedded instance.

**A turn is taking minutes.** On a local model most of that is prompt
processing rather than generation — the status line's `ttft` is the honest
number. A cloud provider trades that for network latency and privacy.

**It quit with no message.** `gaia-tui status` shows the background service and
what is installed.

**Is it running on Vulkan, ROCm or the CPU?** `gaia-tui status` prints a
**Model server** line, and `/provider` shows the same under **Local**:

```text theme={null}
Model server:        Lemonade 2026.41.1 (GAIA's own) at localhost:51234 · Qwen3.6-35B-A3B-GGUF on Vulkan (default), 64K ctx
```

`(default)` means Lemonade picked the backend; `unknown` means this Lemonade
does not report it. To choose one, run `gaia config set llamacpp_backend rocm`
(or `vulkan`, `cpu`, `auto`), or use Settings → Advanced → Model server in the
Agent UI, which lists only the backends this PC can run. It applies the next
time the chat model loads.

## Next steps

* [CLI reference](https://amd-gaia.ai/docs/reference/cli.md#terminal-ui-gaia-tui) — the non-interactive
  subcommands (`run`, `chat`, `status`) and their exit codes.
* [Driving the TUI programmatically](https://amd-gaia.ai/docs/guides/mcp/tui.md) — the control API, for tests
  and assistants. Not needed for normal use.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.