agentknit-tui
A Textual TUI front-end for agentknit coding agents.
Features unique to this harness (things Claude Code and Codex do not do):
- Side questions. Type while a turn is running and the prompt is answered as a side question — a separate read-only LLM call over a snapshot of the conversation, rendered next to the turn without touching the turn's context or progress.
- Token-budget countdown at deciles. The agent runs under a hard
token budget; the log prints
remaining/budgetonly when usage crosses into a new 10% band, instead of nagging after every call. - Read-through streaming. Scrolling up detaches the view from the end: the agent keeps streaming into the log, but nothing yanks you back down. Scrolling to the bottom re-attaches the follow.
- Paste-safe rendering. No
│gutters, no box-drawing borders, no right-hand padding on any rendered line — copying a selection (or a whole block) yields the payload text exactly. - Per-folder prompt history shared with the REPL. The TUI and the
agentknit REPL read and write the same per-directory history file, so
↑recalls prompts typed in either front-end, scoped to the folder they were typed in. - Quota vs rate-limit labeling. HTTP 403 is reported as "Quota" (exhausted window), 429 as "Rate limited" — providers that use 403 for quota are not misreported.
- Clipboard that works in VTE terminals. Copy tries the platform
tool (
xclip/xsel,wl-copy,pbcopy,clip.exe) and emits OSC 52; one of the two reaches the system clipboard even in terminals (Terminator, older gnome-terminal) that ignore OSC 52. - Word-level diff highlighting.
str_replaceedits render as colorized unified diffs with the changed words inside each modified line bolded on a dark background — a one-word change in a long line is visible at a glance. Copied diff lines paste clean.
Everything else is standard TUI furniture: one conversation pane, a multiline prompt, tool calls/results/token accounting inline, a live status bar. The TUI is a pure subscriber to the event stream from agentknit.
Install
pip install agentknit-tui
It depends on agentknit, textual, and rich.
Usage
agentknit-tui # default: glm-5.2 via z.ai
agentknit-tui glm-5.2
agentknit-tui "qwen3-8b" "https://openrouter.ai/api/v1"
agentknit-tui --session <id> # resume a previous trajectory
agentknit-tui --non-interactive # drop ask_user* tools from the schema
agentknit-tui --no-strict-cache-proof
Key bindings
| key | action |
|---|---|
Enter |
submit the prompt |
Shift/Ctrl/Alt+Enter |
insert a newline |
↑ / ↓ |
recall past prompts (same folder, shared with the REPL) |
Esc / Ctrl+C |
cancel the running turn (or quit when idle) |
Ctrl+Shift+C |
copy the mouse selection in the log |
Ctrl+L |
clear the on-screen conversation log only |
While reading: scrolling up (mouse wheel, or PageUp with the prompt
focused) detaches the view from the end — new messages keep arriving in
the log but no longer pull you back down, so you can keep reading while
the agent works. Scrolling back to the bottom re-attaches the
auto-follow. PageDown pages down and snaps to the end when a page
away.
Mouse
- Drag over the conversation log selects text in place (highlighted as
you drag);
Ctrl+Shift+Cthen copies the selection (plainCtrl+Calso works when your terminal delivers it).Escclears the selection. - Paste into the prompt with the terminal's own paste (
Ctrl+Shift+V,Shift+Insert, or middle-click) —Ctrl+Vinside the TUI only reads text copied within the TUI. - Copying tries the platform clipboard tool first (
xclip/xsel,wl-copy,pbcopy,clip.exe) and also emits OSC 52; one of the two reaches the system clipboard even in VTE terminals that ignore OSC 52 (Terminator, older gnome-terminal). - Every line the TUI renders is paste-safe: turns, replies, diffs and tool
output carry no
│gutters or box-drawing borders, and no right-hand padding — copying a selection (or a whole block) yields the payload text exactly. Copied lines are trimmed of any trailing filler.
Ctrl+L (and the TUI's built-in /clear alias) wipes the displayed log
and zeroes the token counters in the status bar; the agent's message
history — the context sent to the model — is untouched, and /usage
still reports the session's full totals.
Status bar
The line under the prompt always shows the model, working directory, and
total tokens in the format <model> - <working directory> - <tokens>.
While a turn is running, the task the agent is working on appears below it,
wrapped over two terminal-width lines so long prompts stay readable.
To reset the LLM context (session history, keeping the system prompt), run
/reset-context in the TUI; it forwards to agentknit's /clear handler.
Slash commands (/help, /usage, /clear, /compact, /model, /reset-context, /exit)
are forwarded to agentknit's command registry; their printed output is
captured and shown inline.
str_replace diffs
Edits made through the str_replace tool are shown as a colorized unified
diff instead of the tool's argument dump: deleted lines in red, added lines
in green, and the specific changed words within each modified line
highlighted in bold on a dark background, so a one-word change inside a long
line is visible at a glance. Each row carries the file's real line number
plus the +/- marker, separated from the content by spaces only — no
vertical-bar gutter, so copied diff lines paste clean.
--- pkg/mod.py
+++ pkg/mod.py
@@ -1,4 +1,4 @@
-def greet(name):
- # say hello to the user
- print("hello " + name)
+def greet(name, greeting="hi"):
+ # greet the user
+ print(greeting + " " + name)
return None
On exit the TUI prints the command to resume the session on the console, exactly like the end of the agentknit REPL:
Resume: agentknit-tui glm-5.2 --session <session-id>
Set AGENTKNIT_RESUME_COMMAND to override the program prefix (wrappers
embedding the model already do this); the --session <id> suffix is always
appended.
Design notes
- The agent loop (
agentknit.run_turn) is synchronous and blocking and emits typed events through a sessionon_eventcallback. The TUI runs each turn in a Textual worker thread and forwards every event onto a thread-safe queue; a 50 ms UI-thread timer drains the queue and renders each event's pre-formatted ANSI string into a Rich renderable. - agentknit's
fmtstrings are raw\033[…]ANSI escapes (not Rich markup), so they are decoded withrich.ansi.AnsiDecoderfor faithful colour/style reproduction. - Multi-line input uses
TextArea, so users can paste and edit freely. ACancelTokenis wired to the cancel bindings so a turn can be interrupted cooperatively, exactly like Ctrl+C in the REPL. - Prompt history is per-folder and shared with the REPL: both read and
write agentknit's readline history file
(
~/.local/share/agent_probe/repl_history/<md5(cwd)>.hist), so arrow-up recalls instructions typed in either front-end, scoped to the folder they were typed in.↑on the first prompt line walks back,↓forward, and any edit drops back to normal typing. - On exit the TUI mirrors the REPL's teardown: the trajectory snapshot is
saved (if the session has any messages), a
session_endrecord is appended to the session log, and — after Textual restores the plain console — the same dimResume: …line the REPL prints is echoed so the session can be continued with--session <id>. - agentknit installs a module-level SIGINT handler (meant for the
foreground REPL) that kills the active tool subprocess. The TUI
neutralises it for each turn's duration and drives cancellation through
the
CancelTokeninstead.
License
MIT.
Release files for agentknit-tui 0.1002.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| agentknit_tui-0.1002.0-py3-none-any.whl | Python 3 | none | any | Details |
Release files / agentknit_tui-0.1002.0-py3-none-any.whl
| Download URL | agentknit_tui-0.1002.0-py3-none-any.whl |
|---|---|
| Size | 34.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
40ae37c7d1fa8b9749fa2a8c47052e88de9fd47c9cfaa5eaf0d423f032736d85
|
|
BLAKE2b-256 checksum How to use checksums |
a1f025c2cb059a6299d9e09e3890acffedc815d45ca95babf1205f58ceab8541
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency log