Terminal client for the Longmen self-hosted coding assistant (requires a running Longmen gateway)
Project description
longmen — Terminal Client
A thin async terminal client for the Longmen self-hosted coding assistant. It connects to a Longmen Gateway over WebSocket, streams model output to the terminal, and handles tool approval dialogs interactively.
Note: This package is a client only. It does not run a language model or execute tools; it is a front-end that connects to a Longmen Gateway. The gateway communicates with a local vLLM model server and an optional RAG service. A running gateway is required. See the main project for deployment instructions.
Requirements
- A running Longmen Gateway — the server this client connects to. Deploy it from the main project using Docker Compose. A reachable gateway is required for the client to function.
- Python 3.12 or newer.
Install
longmen is a command-line application. Installation with
pipx is recommended, as it isolates the application in a
dedicated environment and adds it to PATH:
# 1. Install pipx (once) — see https://pipx.pypa.io/stable/installation/
python3 -m pip install --user pipx
python3 -m pipx ensurepath
# Restart the shell afterwards so the updated PATH takes effect.
# 2. Install the client
pipx install longmen
Alternatively, install with pip into the current environment:
pip install longmen
Both methods provide the longmen command.
From source (development)
cd clients/terminal
poetry install
This creates a virtualenv at clients/terminal/.venv and installs all
dependencies including dev tools. Prefix the commands below with poetry run
when working from source.
Run
# Interactive mode (uses ~/.longmen/terminal/config.toml)
longmen
# Override gateway URL
longmen --gateway ws://localhost:8420/ws
# Auto-select a project
longmen --project my-project
# Minimal theme (no colors)
longmen --theme minimal
# Use a specific config file
longmen --config /path/to/config.toml
# Print version
longmen --version
Configuration
On first run, ~/.longmen/terminal/config.toml is created with defaults:
[gateway]
url = "ws://localhost:8420/ws"
[gateway.auth]
mode = "open" # authentication mode
token = "" # auth token
[project]
id = "" # set via /project or --project flag
root_path = "" # informational only — tools run on the gateway host
[display]
theme = "default" # "default" | "light" | "minimal"
show_thinking = false # show model thinking/reasoning chunks
show_token_bar = true # context usage bar after each response
max_output_lines = 200 # truncate long tool output in the display
auto_approve_safe = true # auto-approve "safe"-risk tool calls
[keybindings]
abort = "c-c" # abort in-progress generation
submit = "enter" # submit prompt
multiline = "escape+enter" # insert newline without submitting (Esc then Enter)
[logging]
level = "warning"
file = "" # path for file logging (empty = disabled)
message_log = "" # jsonl file for raw gateway messages
The config lives at ~/.longmen/terminal/config.toml on every platform — it
resolves against your home directory: /home/<you>/… on Linux,
/Users/<you>/… on macOS, and C:\Users\<you>\.longmen\terminal\config.toml
on Windows. Point at a different file with --config /path/to/config.toml.
You can also edit config live with the /config slash command:
/config theme=minimal
/config display.show_thinking=true
/config display.max_output_lines=50
Slash Commands
| Command | Where it runs | What it does |
|---|---|---|
/help |
client | List all commands |
/new |
gateway | Start a new conversation |
/compact |
gateway | Compact conversation context |
/refresh |
gateway | Reload project context |
/permissions |
gateway | Show/manage stored tool permissions |
/config [key=val] |
client | Show or update config |
/project [id] |
gateway | List, switch, or add (/project add <id> <root_path> [description]) |
/status |
gateway | Request gateway status |
/prompt |
gateway | Show the current system prompt |
/quit |
client | Graceful disconnect and exit |
Unknown commands show fuzzy-matched suggestions.
File Attachments
Prefix a file path with @ anywhere in a prompt:
> Explain what this does @config.toml
> What does this diagram show? @architecture.png
> Compare these two files @old.py @new.py
> Check this @/absolute/path/to/file.cpp
> Review @~/notes/design.md
Rules:
@must be at the start of the input or preceded by whitespace — prevents false matches in email addresses- Text files are sent as
filecontent blocks (base64) - Images (
.png,.jpg,.jpeg,.webp,.gif) are sent asimagecontent blocks - Files over 1 MB trigger a warning; files over 10 MB are rejected
Approval Dialog
Note: the interactive approval dialog applies to the gateway's
promptworkflow mode, which is still under development. The only supported mode today isallow_all, where tool calls execute automatically and no dialog is shown. The behaviour below describes the in-progresspromptmode.
When the model wants to run a tool, an approval dialog is shown:
┌─ Shell Command (moderate) ────────────────────────────────────┐
│ pytest tests/auth/ -v │
│ Risk: moderate │
│ Context: Running test suite for auth module │
├───────────────────────────────────────────────────────────────┤
│ [y] Yes — run this command │
│ [n] No — skip │
│ [s] Yes, remember for this session │
│ [a] Always allow (persist across sessions) │
│ [e] Edit command before running │
└───────────────────────────────────────────────────────────────┘
Single keypress — no Enter needed. With auto_approve_safe = true (the default), safe-risk tool calls (read-only operations) are approved automatically with a brief notice.
Troubleshooting
"Connection refused" on startup
The Gateway isn't running or is on a different address. Check:
- Start the gateway stack — see the
main project (Docker Compose). The
gateway listens on
127.0.0.1:8420by default. - Verify the URL in config matches:
grep url ~/.longmen/terminal/config.toml - Override:
longmen --gateway ws://correct-host:8420/ws
AttributeError: 'ClientConnection' has no attribute 'closed'
websockets 15+ renamed the connection class and removed the .closed property. connection.py uses ws.state in (WsState.CLOSING, WsState.CLOSED) via websockets.protocol.State. If you upgrade websockets, verify this import still resolves:
from websockets.protocol import State as WsState
Crash logs
Unhandled exceptions are written to ~/.longmen/terminal/crash.log.
Config file errors
If the config file has a syntax error, longmen prints the parse error and exits. Delete or fix ~/.longmen/terminal/config.toml — a new default is created on next start.
Project Structure
clients/terminal/
├── pyproject.toml # Poetry project — deps, scripts, tooling config
├── poetry.lock
└── src/termassist/
├── __init__.py # __version__
├── cli.py # Entry point — argparse → App.run()
├── app.py # Main loop — two concurrent asyncio tasks
├── connection.py # WebSocket client — connect, reconnect, send/recv
├── protocol.py # Client-side message builders + parse_message()
├── state.py # State machine — idle/streaming/awaiting_approval/etc.
├── config.py # Config loading/saving (TOML)
├── renderer.py # Rich-based output rendering
├── input_handler.py # prompt-toolkit input with tab completion
├── approval.py # Interactive approval dialog
├── slash_commands.py # Slash command registry and parser
├── file_attach.py # @path syntax → base64 content blocks
├── token_display.py # Context budget bar
├── history.py # In-memory conversation display cache
└── themes.py # Color theme definitions
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file longmen-1.0.0.tar.gz.
File metadata
- Download URL: longmen-1.0.0.tar.gz
- Upload date:
- Size: 32.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.4.1 CPython/3.12.3 Linux/6.17.0-1018-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c3e245e79845112fb47072bbfb28fc1d5b1a816fb49896ffd61bb925dd06557
|
|
| MD5 |
76466c03231084278f2767f74b756a7e
|
|
| BLAKE2b-256 |
d680253f0e6c6cc66e591fbd9ed69880256faf33db4ce67221d828d368c40031
|
File details
Details for the file longmen-1.0.0-py3-none-any.whl.
File metadata
- Download URL: longmen-1.0.0-py3-none-any.whl
- Upload date:
- Size: 34.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.4.1 CPython/3.12.3 Linux/6.17.0-1018-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e45416dd1bc9d233d5842beef28db68d7c289befe4ee27806b45606beb1382d2
|
|
| MD5 |
f5ae57b7ccaad4db4b2bb4525c2ca41e
|
|
| BLAKE2b-256 |
84b3c8e767de7f3db39eb806bc317ead7d9ee323ab9db87e99db01facd137eac
|