A Rust CLI + TUI client for NanoGPT.
It is designed for day-to-day chat use in the terminal, with persistent conversations, fast model switching, provider controls, and direct access to NanoGPT endpoints.
- Full-screen TUI by default (
cargo run --) - Agentic chat loop in TUI with XML tool-calling
- Workspace-scoped file, search, shell, and verification tools
- Persistent conversations with quick switching
- Model browser with catalog scopes:
- canonical (
/v1/models) - subscription (
/subscription/v1/models) - paid (
/paid/v1/models)
- canonical (
- Provider routing per model (
/models/{canonicalId}/providers) - Web routing modes for chat (
/webmodeand picker) - Built-in web search tool with all supported providers:
linkup,tavily,exa,kagi,perplexity,valyu,brave
- Markdown rendering in chat (headings, lists, code blocks, inline styles, links)
- API key onboarding in TUI if no key is configured
- Generic API passthrough (JSON + multipart) for full API coverage
cargo build# Default (opens TUI)
cargo run --
# Explicit TUI in current directory
cargo run -- tui
# Explicit workspace root
cargo run -- tui --workspace /absolute/path/to/project
# REPL chat mode
cargo run -- chat --model openai/gpt-5.2 --streamYou can authenticate with:
- environment variable:
NANOGPT_API_KEY - CLI flag:
--api-key - TUI prompt on first run (auto-saved to config)
Tab: switch focus (conversations/input)Enter: send message (input) or open selected conversation (list)Shift+Enter: line break in composer inputCtrl+J: line break fallback for terminals that remapShift+EnterCtrl+N: create new conversationCtrl+R: reload conversation listCtrl+S: save current conversationCtrl+M: open model galleryCtrl+P: open provider routing for current modelCtrl+G: open web provider/mode picker for chat routingCtrl+W: open web-search toolCtrl+H: open helpEsc/Ctrl+C: quit
/help/model <id>/webmode(open picker)/webmode <mode>(set directly, e.g.off,deep,exa-neural,tavily-deep)/system <prompt>/system off/clear/save/history/models/providers/workspace
- Type
/to see command suggestions - Use
Up/Downto select - Press
TaborEnterto autocomplete
In TUI mode, each user message runs through an agent loop:
- model responds normally, or returns one/more XML
<tool_call>blocks - CLI executes those tools inside the active workspace root
- tool results are sent back as XML
- loop continues until the model returns a final user-facing answer
<tool_call>
<tool>read_file</tool>
<path>src/main.rs</path>
<start_line>1</start_line>
<end_line>120</end_line>
</tool_call>list_files(path, optionalrecursive, optionalmax_entries)glob_files(pattern, optionalbase_path, optionalmax_results)grep_files(query, optionalbase_path, optionalinclude_glob, optionalcase_sensitive, optionalmax_results)read_file(path, optionalstart_line, optionalend_line)write_file(path,content) overwrite/createappend_file(path,content)mkdir(path)move_path(from,to)delete_path(path, optionalrecursive)apply_patch(path,search,replace, optionalall)bash(command, optionaltimeout_secs)run_test(optionalcommand, optionaltimeout_secs)run_lint(optionalcommand, optionaltimeout_secs)bash_session_start(optionalpath, optionalshell)bash_session_run(session_id,command, optionaltimeout_secs)bash_session_output(session_id, optionalmax_chars)bash_session_kill(session_id)git_status(optionalshort)git_diff(optionalstaged, optionalpath)git_add(pathorall=true)git_commit(message)
- Default workspace root is the current directory where TUI is launched
- Use
--workspaceto override - File tools are restricted to that workspace root
- Bash tool runs with that workspace as current working directory
cargo run -- models --scope canonical --detailed
cargo run -- models --scope subscription --detailed
cargo run -- models --scope paid --detailedcargo run -- models --show-providers-for openai/gpt-oss-120bcargo run -- web-search "latest AI news" --provider linkup --depth standard
cargo run -- web-search "rust lang updates" --provider exa --depth fast
cargo run -- web-search "market headlines" --provider brave --depth deepcargo run -- responses create --model openai/gpt-5.2 --input "Summarize this"
cargo run -- responses info
cargo run -- responses get <response_id>
cargo run -- responses delete <response_id>cargo run -- balance# JSON request
cargo run -- api --method POST --path /v1/embeddings \
--json '{"model":"text-embedding-3-small","input":"hello"}'
# Multipart request
cargo run -- api --method POST --path /transcribe \
--form model=whisper-1 \
--form-file file=/absolute/path/audio.mp3- Config:
~/.nanogpt-cli/config.json - Conversations:
~/.nanogpt-cli/conversations/*.json
This repo includes a manual GitHub Actions release workflow that:
- builds Linux x64 and macOS arm64 binaries
- packages artifacts and checksums
- creates a GitHub Release from a manually provided tag