LLM chat and agent toolkit
Project description
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:
pdm run basedpyright .
pdm run ruff check .
pdm run ruff format .
pdm run pytest
Basic usage
# 1) Create / open config
plyngent config path
plyngent config edit # needs $EDITOR
# 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 # 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 (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 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 /markdown /tools /rounds |
Toggles and limits |
| /retry | Re-run incomplete last user turn (after error/cancel) |
| /provider /model | Switch without restarting |
| /models | List config + remote GET /models (--refresh bypasses cache) |
| /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 (POSIX openpty; Windows ConPTY via pywinpty), 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
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 plyngent-0.1.0.tar.gz.
File metadata
- Download URL: plyngent-0.1.0.tar.gz
- Upload date:
- Size: 130.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e314a5437ec1a00bb32a11755df324e7cea0d49a265bebfab4561ea408710761
|
|
| MD5 |
0d60736fa274eb0bdf14b3dced89faba
|
|
| BLAKE2b-256 |
e8d36dbddae2e3b0e6f1c2289b481a177b3f22d99c2f212ba4f474d73d20de7f
|
Provenance
The following attestation bundles were made for plyngent-0.1.0.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.0.tar.gz -
Subject digest:
e314a5437ec1a00bb32a11755df324e7cea0d49a265bebfab4561ea408710761 - Sigstore transparency entry: 2173174673
- Sigstore integration time:
-
Permalink:
NCBM/plyngent@6a1160f1e3fe5197c64ef442c03afe62c0e00802 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/NCBM
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@6a1160f1e3fe5197c64ef442c03afe62c0e00802 -
Trigger Event:
push
-
Statement type:
File details
Details for the file plyngent-0.1.0-py3-none-any.whl.
File metadata
- Download URL: plyngent-0.1.0-py3-none-any.whl
- Upload date:
- Size: 126.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b54a6eef80d67daea96f790d22b5296cb6ab304d48ee5a8dad1f433876c99a9d
|
|
| MD5 |
63a2c80c8cce150e2f654ce36781f117
|
|
| BLAKE2b-256 |
8515233fa65c8e209703356c293419ab2992d2e769e2c6c4b31a230dbae5acbd
|
Provenance
The following attestation bundles were made for plyngent-0.1.0-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.0-py3-none-any.whl -
Subject digest:
b54a6eef80d67daea96f790d22b5296cb6ab304d48ee5a8dad1f433876c99a9d - Sigstore transparency entry: 2173174709
- Sigstore integration time:
-
Permalink:
NCBM/plyngent@6a1160f1e3fe5197c64ef442c03afe62c0e00802 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/NCBM
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@6a1160f1e3fe5197c64ef442c03afe62c0e00802 -
Trigger Event:
push
-
Statement type: