AgentBridge Terminal UI β user guide
The console app of AgentBridge is an interactive terminal UI built on
Terminal.Gui (v2, instance-based API),
modelled on Qwen Code's TUI: a menu bar,
an AGENT logo panel, a streaming chat panel with an input line at the bottom, a
status bar, / slash commands with a filterable command palette, @ file
attachments, keyboard shortcuts, mouse support and online help β while the HTTP
server keeps serving every other client on the same port. CLI and API are the
same conversation: messages you send from the UI go through the exact same
POST /v1/chat/completions endpoint that OpenAI-compatible clients use, while MCP
clients can control the same runtime via POST /mcp, so both can drive the agents
at the same time (the UI holds one session; other
clients create their own).
How Qwen Code's TUI works (the model we followed)
Qwen Code is a terminal-based agentic coding tool: you launch qwen in a
project and get a persistent TUI where:
- a bottom input field accepts plain-language prompts; a small status line shows the model/provider and context usage;
- typing
/opens a slash-command palette β a contextual help list (name + one-line description per command) that filters as you type; Enter runs the highlighted command, Tab completes it, Esc closes it; @opens file/context completion;- a rich keyboard-shortcut layer covers editing (Ctrl+A/E/U/K/W, word
jumps), history (Up/Down, Ctrl+R reverse search), Ctrl+C cancel, Ctrl+L
clear screen,
?shortcuts overlay, Tab ghost-text completion; /modelswitches the LLM on the fly,/helpshows the command docs,/docsopens the online documentation in the browser;- agent replies stream into the conversation and can be cancelled.
What AgentBridge does better
| Qwen Code | AgentBridge (this app) |
|---|---|
| TUI is the only front-end | TUI and the OpenAI-compatible API simultaneously, same process β any SDK/script can keep driving the agents while you chat |
| Model switch is provider-side | /model switches LLM with a context-window guard β the server refuses (409) when the conversation overflows the target provider's window and explains why |
| Mouse: scroll + click | native cross-platform mouse (Terminal.Gui): wheel scrolls the conversation and menus, click positions the input cursor or selects a list row, double-click runs the selected item |
| Menus | pickers are drawn inside the TUI layout β Esc always cancels (/model, /agent, /attach) with a clean screen, no residue |
| No voice | /voice β dictation from the server microphone (Windows), /tts β Kokoro neural TTS speaks the replies and plays the WAV |
File completion via @ |
@ palette of uploaded files (server-side /v1/files), /files add <path> uploads and attaches; attachments ride along as file_ids |
| Status shows context | status bar also shows history tokens / context window, the active tools (readable names, e.g. File, Web, Git), TTS/mic availability |
/docs opens docs site |
/docs opens this project's online README; /help lists commands, shortcuts, API endpoints and links |
| β | /agent opens the tools checklist (presets + individual tools), /features toggles feature flags, /health pings the server, /retry resends the last prompt, /web opens the auto-connected web client |
Commands (type / for the live list)
| Command | What it does |
|---|---|
/help Β· /? |
Full help: commands, shortcuts, API endpoints, online docs |
/docs |
Open the online documentation in the browser |
/web |
Launch the Giraffe AI web client (auto-installed/updated), auto-connected to this server |
/modelsetup |
Configure LLM models & providers (add/edit/remove, active model, API keys) |
/model [name] |
Switch the LLM provider (menu when no name given; context-window checked) |
/agent [name] |
Choose the agent tools: quick presets or an individual-tool checklist (Space toggles; see below) |
/voice [lang] |
Dictate from the server microphone into the input |
/tts [text] |
Speak the last agent reply (or the given text) β Kokoro TTS, WAV playback |
/telegram status|config [set <key> <value>|reload]|login-code <code>|allow|disallow <user> |
Telegram chat medium: bare /telegram opens the interactive panel (status, login code, allow-list, config), the subcommands cover the same actions (see Telegram) |
/features [name] [on|off] |
Show or toggle session feature flags (voice, tts, ...) |
/new Β· /reset |
Start a new session (fresh conversation) |
/clear |
Reset the current session history (keeps the session) |
/status |
Session state + platform capabilities |
/files add <path> Β· /files rm <id> Β· /files |
Upload+attach a file, delete one, list uploads |
/attach [id] |
Toggle a file attachment for the chat (menu when no id) |
/shortcuts Β· /keys |
Keyboard shortcuts overlay (also press ? on an empty input) |
/health |
Ping the server, report latency |
/retry |
Resend the last prompt (also Ctrl+Y) |
/exit Β· /quit |
Exit (also Ctrl+C twice, or Ctrl+D) |
Web GUI
/web (or the menu Web β GUI) opens the agents in your browser. The
Giraffe AI client β a single static
index.html plus its own launcher β is not part of this repository: on startup the
server installs it next to the executable (GiraffeAIWebClient\ folder, from the client's
latest GitHub release). The first install is unconditional; the automatic update check
follows the app's auto-update toggle (--no-update / File β Auto-Update). Then /web
runs the platform launcher (start.bat / start.sh), which serves the client on
http://localhost:8000 and opens the browser.
The launch passes --provider with this server's endpoint, so the client registers the
AgentBridge provider (if not already present) and selects it immediately β no manual
configuration, just start typing.
- The first download needs an internet connection (GitHub); afterwards the client is fully local.
- The client runs in its own launcher window/process and keeps serving after the TUI exits.
- The browser talks straight to this server (
POST /v1/chat/completions), so CORS is enabled and no API key is needed for local use.
Agent tools
/agent [name] switches to a preset β full ids: default-agent, web-agent,
search-agent, research-agent, document-files, spreadsheet-files, email-agent,
office-files, multi-files, all-files. Bare /agent (or menu Tools β Agent & Tools)
opens the tool checklist dialog:
- Core (always on) β the first line lists the locked core tools (
FileTool,GitTool): always active, not toggleable; the only way to change their status istools.json(see MANUAL.md β the picker always reflects the effective state). - Active tools below β every non-core tool actually loaded at runtime (core tools +
the plugins in
Tools/), each with a one-line description. Space toggles a tool; Close/Esc saves the marked set as a custom combination (sent to the server as the additivetoolsfield, which overrides the preset'smodel). The enabled core tools are always part of the combination.
all-files is the dynamic all-in-one agent: every loaded tool the per-tool config leaves
enabled (class-A plugins ON by default; class-B OfficeTool OFF unless enabled in
tools.json).
The status bar shows the active tools with readable names (tools: File, Web, Git), so
you always know what the agent can do in this conversation.
Telegram chat
/telegram turns AgentBridge into a Telegram chat client (a userbot): people write to
the account in a private chat, the message (text and/or file attachments) goes through
the same per-user chat session as the TUI and the HTML client, and the reply β text plus
any files the agent attaches β comes back into the same chat. Text chat only: the Telegram
Client API has no audio-call support, so Telegram is not a voice medium (see
docs/telegram.md).
Bare /telegram (or menu Tools β Telegram) opens an interactive panel: live
status plus the first-login code field, allow/disallow user, config, reload and
enable/disable β no slash-command syntax to remember. The subcommands below drive the
same actions from the command line:
| Command | What it does |
|---|---|
/telegram status |
Live state: enabled, phase (off/conn/code/2fa/on/err), logged-in user, allow-list, agent |
/telegram config |
Show the effective configuration (phone, session, allow-list, agent) |
/telegram config set <key> <value> |
Change one config key and persist it to telegram.json (connection keys restart the bridge) |
/telegram config reload |
Re-read telegram.json (hand edits made outside the TUI) and apply them |
/telegram login-code <code> |
Complete the pending first login (verification code or 2FA password) |
/telegram allow <user> Β· /telegram disallow <user> |
Add / remove an allow-list entry (numeric id or @username) |
The status bar shows a tg: segment (off/conn/code/2fa/on/err), refreshed
by the same 3-second poll as SIP. When an agent reply carries attached files, the chat
history shows them as [attachment: <path>] lines β the files are saved under an
attachments/ folder next to the executable.
The first login is TUI-guided: /telegram status shows code while the verification code
is pending, /telegram login-code <code> completes it (a 2FA password, if the account has
one, is submitted the same way), and the session persists in telegram.session β no code
is asked again. Configuration lives in telegram.json next to the executable (excluded
from updates); edit it by hand, with the setup scripts (scripts/setup-telegram.bat on
Windows, scripts/setup-telegram.sh on Linux/macOS), or with these commands. Full
reference: docs/telegram.md.
Models & Providers setup
/modelsetup (or menu File β Models & Providers) opens a tabbed window that mirrors the
AIOffice settings panel:
| Tab | What you can edit |
|---|---|
| LLM & Providers | Active provider (dropdown, switches via the same path as /model) and a provider list with Addβ¦ / Editβ¦ / Remove β the CRUD operations apply immediately and persist to providers.json (see below) |
| Email (SMTP) | SMTP server, port, user, password and the recipient email |
| Mail (IMAP) | IMAP server, port, user and password |
| General | Step logging on/off (logs/ folder) and the documents path (re-indexed on change) |
- Field edits (email, general) apply when you press Save; Close discards them.
- Adding a provider opens a small form (name, protocol OpenAI/Gemini/Anthropic, interaction
mode Default/API/CLI, model, base address, endpoint path, API key, context window,
timeout). The API-key field serves every cloud provider β any provider whose endpoint is
not on loopback (
localhost/127.0.0.1) needs one; local providers simply leave it empty. Keys are stored per-provider inproviders.json(masked on screen while typing). Editing replaces the config in place; removing refuses to delete the last remaining provider. The interaction mode is optional:Default(the initial choice) leaves the decision to the model size β CLI for small models, API for large ones;API/CLIforce one of the two. The active mode appears on the status page and is reported byGET /v1/modelsasinteraction_mode. - The provider list also stays in sync with
GET /v1/models, so an added provider can be switched to right away.
Auto-update
Menu File β Auto-Update toggles the automatic update check performed at startup
(checked = enabled, the default). The choice persists to the OS app-data folder
(<AppData>\agent\autoupdate.json), so it survives updates. When a newer release is
found, the app downloads it, swaps the files and restarts itself β see
autoupdate.md for the architecture and --no-update for services.
Keyboard shortcuts
| Shortcut | Action |
|---|---|
Enter |
Send the message / run the selected command |
/ |
Open the slash-command palette (live, filters as you type) |
@ |
Open the file palette (toggle chat attachments) |
? |
Shortcuts overlay (empty input) |
Tab |
Complete the selected command in the palette |
Esc |
Close dialog Β· clear input Β· twice: exit |
Ctrl+C |
Cancel the reply Β· clear input Β· twice: exit |
Ctrl+D |
Exit (empty input) |
Ctrl+L |
Clear the session history (menu bar too) |
Ctrl+R |
Reverse-search prompt history |
Ctrl+Y |
Retry the last prompt |
Up / Down |
Prompt history (also Ctrl+P / Ctrl+N) |
β / β |
Move the cursor (with Ctrl: by word) |
Ctrl+A / Ctrl+E |
Select all / jump to end of the input |
Ctrl+U / Ctrl+K |
Delete to start / to end of the line |
Ctrl+W |
Delete the word before the cursor (also Ctrl+Backspace) |
PgUp / PgDn |
Scroll the conversation history |
F1 |
Full help page |
F10 |
Activate the menu bar |
The conversation auto-follows the stream while you are at the bottom; scrolling up
(wheel or PgUp) pauses the follow so you can read, and scrolling down or sending a
message resumes it.
Mouse
Terminal.Gui provides native cross-platform mouse support: menus and dialogs are
rendered inside the layout and Esc always cancels them cleanly (/model,
/agent, /attach).
| Action | Effect |
|---|---|
| Mouse wheel (conversation) | Scroll the history |
| Mouse wheel (dialog/list) | Move the selection |
| Click the input line | Position the text cursor |
| Click a dialog/list row | Select it |
| Double-click a list row | Run it |
The terminal switches to the alternate screen buffer and restores it on exit.
Localisation
The TUI is fully localised for EN, IT, FR, ES, DE, RU using the standard .NET
resource-file approach (Resources/Dictionary.resx + per-language satellites). The app
runs in the system language when supported, otherwise English β the correct file is
selected automatically via CultureInfo.CurrentUICulture (a French system picks fr, a
German one de, any other culture falls back to the neutral English resource).
| File | Language |
|---|---|
Resources/Dictionary.resx |
English (neutral default) |
Resources/Dictionary.it.resx |
Italian |
Resources/Dictionary.fr.resx |
French |
Resources/Dictionary.es.resx |
Spanish |
Resources/Dictionary.de.resx |
German |
Resources/Dictionary.ru.resx |
Russian |
Rules and conventions:
- Command names are never translated β
/help,/model,/agent,/voice,/tts,/files, β¦ keep their English names in every language (they are also the API contract). Only the command descriptions shown in the palette/help are localised. - All UI strings (menus, help pages, dialogs, status notes, picker hints) come from
Dictionary.*(the strongly typed Designer generated from the resx). New UI strings go into the resx files, never hardcoded inTui.cs. - System-generated agent results are localised too. AIOrchestrator no longer returns
hardcoded English messages ("Max iterations reached", "LLM returned no response", the
"Done" fallback): it returns a locale-neutral
AgentResultCodeenum and AgentBridge maps each code to the phrase in the dictionary for the current language (seeAgentResult.cs/Program.csβResultText). The agent's own LLM text passes through untouched, since the model is instructed to reply in the language of the request. - Voice/TTS languages (
/voice,/tts) keep followingSystemLang(machineCurrentUICultureviaSystemLang.Get()), independently of the UI dictionary.
To add a new language: copy Resources/Dictionary.resx to Dictionary.XX.resx
(XX = ISO 639-1 code), translate the values, and rebuild β the SDK picks the new satellite
up automatically.
Launch modes
How the app starts β terminal UI, server only, or forced UI β is covered in docs-dev/ARCHITECTURE.md.
See also: README Β· API reference Β· Architecture Β· Developer guide (Terminal.Gui v2, for TUI code changes β developers, not shipped)