Rbebelm installs a serious terminal UI as a native Rust
binary compiled during R package source installation. The binary follows
ARF’s separation of concerns:
GET /stream NDJSON events,
POST /command typed commands, and POST /rpc
JSON-RPC compatibility./reload. Extensions are registered by R; frontends refresh
local keybindings, widgets, palettes, and file watchers when catalogs
change.The TUI source lives in src/rust/src/bin/rbebelm-tui.rs.
A normal source install builds both the R backend libraries and the TUI
binary:
The compiled binary is copied into the installed package
bin/ directory:
For direct development checks without a full R install:
The default config path follows the platform config directory:
~/.config/rbebelm/tui.toml~/Library/Application Support/rbebelm/tui.toml%APPDATA%\\rbebelm\\tui.tomlStart an R-owned loop endpoint and attach the TUI with one command:
TUI="$(Rscript -e 'cat(system.file("bin/rbebelm-tui", package = "Rbebelm"))')"
"$TUI" run --weights /path/to/LFM2.5-8B-A1B-Q4_K_M.ggufOr configure the weights in BEBELM_WEIGHTS_FILE /
startup.weights and run the binary with no subcommand, like
pi starts interactive mode by default:
run starts the R host, waits for readiness JSON,
attaches chat, and stops the R host when the TUI exits.
For split-terminal, remote, editor, or automation workflows, start only the R-owned loop endpoint:
"$TUI" headless \
--weights /path/to/LFM2.5-8B-A1B-Q4_K_M.gguf \
--url http://127.0.0.1:8080 \
--jsonThis command requires the installed R package plus optional
nanonext and later, because the loop endpoint
is an R-level optional surface. The URL can be local HTTP, remote HTTP,
or HTTPS/TLS when the R server is created with
nanonext::tls_config(). Headless mode is the R host side of
the ARF-inspired split; terminal/editor clients attach to it.
Use the stream as the rendering/event backbone and commands as the control path:
"$TUI" stream --url http://127.0.0.1:8080
"$TUI" command --url http://127.0.0.1:8080 --type session_info --params '{}'
"$TUI" command --url http://127.0.0.1:8080 --type catalog --params '{}'
"$TUI" command --url http://127.0.0.1:8080 --type turn \
--params '{"prompt":"Say hi","max_steps":2}'
# JSON-RPC compatibility/control API:
"$TUI" rpc --url http://127.0.0.1:8080 --method session/infoAttach the ratatui chat frontend to the running loop endpoint:
Keys and slash commands:
Enter: submit the current prompt or slash commandTab: complete slash commands after /Backspace: edit the promptCtrl-L: clear the local screenCtrl-Q, /quit, /exit,
/q: quit/help,
/commands, /tools, /state,
/transcript, /clear, /allow-eval,
/no-eval, /graphics [device],
/r <code>, /rplot [plot-code]Direct /rplot is a user command and creates a simple
plot when no code is supplied. Model-side r_eval and
r_plot are enabled by default for local TUI hosts; use
--no-eval at startup or /no-eval at runtime to
remove them from the model tool catalog. Use
/graphics auto|native|png|jgd|devout-ascii to inspect or
change plot handling.
The current UI is intentionally small: it is a frontend shell around
R-owned agent semantics. That keeps consoles, transport clients, and TUI
consumers aligned. Runtime extension registration happens in R via
bebel_loop_register_extension() /
bebel_loop_unregister_extension() and emits
catalog_changed events for frontends.
Plots are managed by R, not by the terminal frontend.
r_plot and /rplot use the configured R
graphics device: auto, native,
png, optional jgd, or optional
devout-ascii. TUI/headless sessions default to PNG
artifacts unless a jgd socket is configured. The TUI marks PNG output as
an image/png artifact, shows the path, and renders a
portable braille thumbnail from the PNG bytes so thin base-R axes/points
survive terminal rendering better than plain ASCII. Full-color inline
pixel preview still needs a terminal image protocol backend (Kitty
graphics, iTerm2 inline images, or sixel), while a jgd-compatible
graphics stream would be the richer vector/event renderer boundary. The
TUI does not own an R graphics device.
Real frontend/device check from the repository root:
This target uses a Rust PTY runner plus optional R packages
nanonext and later. It installs the current
package, starts a fake loop endpoint, launches the installed
rbebelm-tui through a pseudo-terminal, submits
/rplot, and verifies that the terminal rendering contains
an image/png artifact plus a braille thumbnail. It is
intentionally outside R CMD check because it requires a
real terminal.
Non-model command checks after package installation:
TUI="$(Rscript -e 'cat(system.file("bin/rbebelm-tui", package = "Rbebelm"))')"
"$TUI" config default
"$TUI" config pathEnd-to-end test with a local model, one terminal:
Split-terminal endpoint test:
# terminal 1
"$TUI" headless \
--weights /path/to/LFM2.5-8B-A1B-Q4_K_M.gguf \
--url http://127.0.0.1:8080 \
--json
# terminal 2
"$TUI" stream --url http://127.0.0.1:8080
"$TUI" command --type session_info --url http://127.0.0.1:8080 --params '{}'
"$TUI" command --type turn --url http://127.0.0.1:8080 \
--params '{"prompt":"Say hello from the TUI check","max_steps":1}'
"$TUI" chat --url http://127.0.0.1:8080