plyngent
Single-user LLM chat and agent toolkit for the terminal.
Python 3.14+. OpenAI-compatible APIs (including DeepSeek OpenAI-compat), OpenAI Responses with optional hosted tools, SQLite session memory, workspace-scoped file/process/VCS tools, and a readline REPL with slash commands.
Requires Python 3.14+ on your PATH (or via uv / pipx).
Install
Quick try (uvx)
No permanent install — runs the published package in a temporary environment:
uvx plyngent --help
uvx plyngent chat
User tool install
Keep plyngent on your PATH as a managed tool:
# uv (recommended)
uv tool install plyngent
plyngent --help
# pipx
pipx install plyngent
plyngent --help
Upgrade later:
uv tool upgrade plyngent
# or: pipx upgrade plyngent
pip (venv or user)
python3.14 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -U pip
pip install plyngent
plyngent --help
Or user install (if you accept that layout):
pip install --user plyngent
From a git clone (development)
pdm install # first time
pdm sync # after pull
pdm run plyngent --help
Dev checks (same order as CI):
pdm run ruff check .
pdm run ruff format --check . # or: pdm run ruff format . to apply
pdm run basedpyright .
pdm run pytest
Commit gateway (prek): runs ruff check + format and basedpyright on git commit so format is not forgotten.
uv tool install prek # once
prek install # once per clone (installs .git/hooks/pre-commit)
prek run --all-files # run all hooks on demand
Config: prek.toml. CI still runs the same checks in GitHub Actions.
Basic usage
# 1) Create / open config
plyngent config path
plyngent config edit # $VISUAL/$EDITOR, else system open (xdg-open/open/startfile)
# Minimal provider (OpenAI platform — Responses API; preset defaults to openai):
# [providers.oai]
# access_key_or_token = "sk-..."
# # models default: gpt-5.4, gpt-5.4-mini, gpt-5.4-nano
# # provider_tools default: web_search (use provider_tools = [] to disable)
# 2) Chat
plyngent chat
plyngent chat --provider oai --model gpt-5.4-mini
plyngent chat -p "Summarize this repo" --provider oai --model gpt-5.4-mini --no-stream
# 3) List providers from config
plyngent providers
In the REPL: type normally, use /help for slash commands, """ … """ for multiline, /markdown for Rich rendering, /quit to leave.
Configure
Default config path (platformdirs):
plyngent config path
plyngent config edit # $VISUAL/$EDITOR (e.g. codium --wait), else system default
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 (default if preset is omitted; default models gpt-5.4 / gpt-5.4-mini / gpt-5.4-nano when models is omitted), 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 unset/empty), chat uses a durable file under the user data dir (e.g. ~/.local/share/plyngent/chat.db on Linux). Set url = ":memory:" for a true in-memory SQLite (CLI warns; no file; useful for tests).
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 |
YOLO on: skip destructive-tool confirms for this process |
--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$VISUAL/$EDITOR(blocking only; empty 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|last] |
Recent messages (default preview; last/1 = full + markdown) |
/history --full |
Full bodies for the selected window |
/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 /markdown /tools /rounds |
Toggles and limits |
/yolo [on|off|once] |
Soft destructive confirms: sticky skip, off, or next turn only |
| /retry | Re-run incomplete last user turn (after error/cancel) |
| /provider /model | Switch without restarting |
| /model --persist | Save current model id into plyngent.toml catalog |
| /models | List config + remote GET /models (always re-fetches) |
| /models --persist | Merge remote catalog into TOML for this provider |
| /todos | Todo/task stack: list, push, pop, done, clear |
| /config | Edit plyngent.toml ($VISUAL/$EDITOR or system open); reload after blocking editor |
| /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 (including tree with default noise-dir skips), run_command / PTY (POSIX openpty; Windows ConPTY via pywinpty), read-only VCS (git), human prompts (ask_user_line / ask_user_choice / ask_user_form), and todo stack tools (todo_list / todo_push / todo_pop / todo_update / todo_clear).
Safety defaults:
- Paths stay under the workspace; optional
path_denylistsubstrings (treealso skips denylisted children by default). - Command basename denylist (e.g. dangerous shells/utilities).
- Destructive tools (delete/move/overwrite) can require confirm (
confirm_destructive; default deny in non-TTY). Override for the session with/yolo on|off|onceor startup--yes(path/command denylists still apply). - PTY sessions: caps, idle TTL, output budget; master FD is non-inheritable; sessions closed on chat exit.
Prefer file tools over full-screen editors (
vim/nano) for edits.read_ptysanitizes CSI/controls so tool results cannot reprogram the host TTY (no host terminal reset on exit).write_ptyis literal text only; usewrite_pty_keysfor\xHH,ctrl+x,key=esc|enter|…. For passwords/sudo/ssh prompts useask_into_pty(human types locally; answer never returns to the model).
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
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 plyngent-0.1.3.tar.gz.
File metadata
- Download URL: plyngent-0.1.3.tar.gz
- Upload date:
- Size: 175.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a41e53254e737fdd38cf3cae4441c744e4840654760c83d368e2e318f2daaf1f
|
|
| MD5 |
14b04eb884b8a6ad8e07089d60328f1f
|
|
| BLAKE2b-256 |
b3c67cb26eb85a9a03c501b79eb6058d200507a537371ac486a6093f97d2606c
|
Provenance
The following attestation bundles were made for plyngent-0.1.3.tar.gz:
Publisher:
python-publish.yml on NCBM/plyngent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
plyngent-0.1.3.tar.gz -
Subject digest:
a41e53254e737fdd38cf3cae4441c744e4840654760c83d368e2e318f2daaf1f - Sigstore transparency entry: 2203526509
- Sigstore integration time:
-
Permalink:
NCBM/plyngent@bec14e76afc4ad2d09c1ff597ca7a0d5dbe603cb -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/NCBM
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@bec14e76afc4ad2d09c1ff597ca7a0d5dbe603cb -
Trigger Event:
push
-
Statement type:
File details
Details for the file plyngent-0.1.3-py3-none-any.whl.
File metadata
- Download URL: plyngent-0.1.3-py3-none-any.whl
- Upload date:
- Size: 164.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
76f673e83338daee4f7d5a44cc55fadbeb0baaa0374571b2a9e4b9700f7e1b8f
|
|
| MD5 |
c51af41749ad28793ebeded92a4613b0
|
|
| BLAKE2b-256 |
bce70302d8cc7bbe4b95b514a280cde8811bd065b71b6c7b1fc6dcf6fea24bf6
|
Provenance
The following attestation bundles were made for plyngent-0.1.3-py3-none-any.whl:
Publisher:
python-publish.yml on NCBM/plyngent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
plyngent-0.1.3-py3-none-any.whl -
Subject digest:
76f673e83338daee4f7d5a44cc55fadbeb0baaa0374571b2a9e4b9700f7e1b8f - Sigstore transparency entry: 2203526543
- Sigstore integration time:
-
Permalink:
NCBM/plyngent@bec14e76afc4ad2d09c1ff597ca7a0d5dbe603cb -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/NCBM
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@bec14e76afc4ad2d09c1ff597ca7a0d5dbe603cb -
Trigger Event:
push
-
Statement type: