plyngent
Single-user LLM chat and agent toolkit for the terminal.
Python 3.14+, managed with PDM. OpenAI-compatible APIs (including DeepSeek OpenAI-compat), SQLite session memory, workspace-scoped file/process/VCS tools, and a readline REPL with slash commands.
Install
# from a clone
pdm install
pdm run plyngent --help
# or editable install into your environment
pdm install
# entry point: plyngent
Dev checks:
pdm run basedpyright .
pdm run ruff check .
pdm run ruff format .
pdm run pytest
Configure
Default config path (platformdirs):
plyngent config path
plyngent config edit # opens $EDITOR (e.g. codium --wait)
Copy the example and fill in a real token:
cp doc/plyngent.example.toml "$(plyngent config path)"
# then edit providers
Minimal shape:
[providers.local]
preset = "openai-compatible"
url = "https://api.openai.com/v1"
access_key_or_token = "sk-..."
[providers.local.models]
"gpt-4o-mini" = { text = true }
[agent]
system_prompt = "You are a careful coding assistant."
confirm_destructive = true
max_context_tokens = 200000
Supported provider presets today: openai, openai-compatible, deepseek (OpenAI convention; default models deepseek-v4-flash and deepseek-v4-pro if models is omitted). Anthropic presets are modeled in config but not wired in the runtime client yet.
If [database] is omitted (or SQLite url is empty/":memory:"), chat uses a durable file under the user data dir (e.g. ~/.local/share/plyngent/chat.db on Linux).
Chat
Interactive REPL
plyngent chat
plyngent chat --provider local --model gpt-4o-mini
plyngent chat --workspace /path/to/project --new
plyngent chat --session 3
| Flag | Meaning |
|---|---|
--provider / --model |
Select from config (required when multiple and non-interactive) |
--workspace |
Tool root (default: cwd); sessions bind to this path |
--new / --session ID |
Fresh session vs resume by id |
--tools / --no-tools |
Default tools on |
--max-rounds |
Tool-loop rounds per turn (default 32) |
--stream / --no-stream |
Streaming deltas (default on) |
--quiet |
Less status on stderr |
--yes |
Allow destructive tools without confirm (also for one-shot) |
--log-level |
On the root CLI: DEBUG, INFO, WARNING, … |
Sessions resume the most recently updated session for the current workspace unless you pass --new or --session. Each session remembers the last provider and model (restored on resume so you are not re-prompted).
One-shot (scripts / CI)
plyngent chat -p "Summarize README.md" --provider local --model gpt-4o-mini --no-stream
echo "hello" | plyngent chat --provider local --model gpt-4o-mini
Exit codes (one-shot):
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Config / usage error |
| 2 | Cancelled |
| 3 | Turn failed (API / incomplete) |
Input ergonomics
- Multiline: start a message with
""", end a later line with""". /edit: compose a turn in$EDITOR(empty buffer cancels).- Tab: completes slash commands and some arguments (provider, model, on/off, export,
/helptargets).
Slash commands
Type /help in the REPL for the live list. Common ones:
| Command | Purpose |
|---|---|
/status |
Provider, session, context/usage estimates |
/history [n] |
Recent messages |
/sessions |
Sessions for this workspace |
/new /resume /rename /delete |
Session lifecycle (/delete confirms) |
/export [md|json] [path] |
Transcript from DB (no secrets) |
/compact |
Soft-compact + model summary into a new session |
/stream /verbose /tools /rounds |
Toggles and limits |
/retry |
Re-run incomplete last user turn (after error/cancel) |
/provider /model |
Switch without restarting |
/config |
Edit plyngent.toml in $EDITOR and reload |
/quit |
Leave the REPL |
User messages are saved immediately. On API error or Ctrl+C, partial assistant/tool output is discarded but the user message stays so /retry works after resume. Interactive auto-retry uses 10s / 20s / 30s delays.
Workspace model
- Workspace = root for file/process/VCS tools (default cwd).
- Session = SQLite chat bound to a workspace path.
- Resuming a session from another directory prompts: keep session workspace, rebind to current, or abort.
Tools (when enabled)
Default registry: file ops, run_command / PTY (Unix), read-only VCS (git), and human prompts (ask_user / choose_user / form_user).
Safety defaults:
- Paths stay under the workspace; optional
path_denylistsubstrings. - Command basename denylist (e.g. dangerous shells/utilities).
- Destructive tools (delete/move/overwrite) can require confirm (
confirm_destructive; default deny in non-TTY). - PTY sessions: caps, idle TTL, output budget; master FD is non-inheritable; sessions closed on chat exit.
Usage / context (CLI)
- Context size prefers API
prompt_tokensfrom the last model call; otherwise a char-based estimate (~4 chars/token). - Turn/session usage sum billed completion usage across tool rounds (history is re-sent each round).
- Soft compact can calibrate from reported
prompt_tokens. See/status.
Other commands
plyngent providers # list configured providers
plyngent config path|edit
plyngent --log-level INFO chat ...
Architecture (short)
See doc/architecture.md and CLAUDE.md for developers.
lmproto/— OpenAI-compatible (+ DeepSeek) msgspec models and async SSE clientsagent/— tool loop, streaming, usage, compactmemory/— async SQLAlchemy sessions/messagestools/— workspace toolscli/— Click entry + slash registry (awaitletbridges sync Click to async work)- Multi-tenant / web (
router/, realweb/) are not in scope for the single-user CLI (Phase H).
License
MIT