Repository navigation
Releases: winterop-com/stabbur
Release list
stabbur 0.12.0
One feature, for anyone who lets a voice-design model read chat replies aloud. If your
Listen voice is a Kokoro preset, nothing here changes for you.
A voice-design model has no fixed speaker: it invents one from a description, and a seed
picks which of the speakers matching that description you get. Until now the chat's
Listen button spoke every reply with the description and seed pinned in stabbur's voice
registry, and nothing in the UI could change either. The only place a description could be
written was the Voice studio, which does not feed Listen.
Two fields now appear beside the voice picker whenever the voice takes them: a Voice
description and a Speaker seed. They live in the two places the voice itself does.
Settings > Voice sets the default every chat inherits, stored in the browser like the
voice and speed. The chat's own settings panel overrides both for one conversation, with
the inherited value shown and a Reset back to it. Blank means the model's own house
voice, so a chat that sets nothing sounds exactly as it did in 0.11. The fields hide when
a Kokoro preset is picked, since a preset is a fixed speaker; what you wrote is kept, so
switching voices and back does not lose it. The Settings picker also stops filing a model
voice under a language it never declared and no longer invents a gender mark for it.
For API clients, POST /api/speak takes two optional fields for a model: voice,
instruct and seed, each falling back to the house voice when unset. A description sent
to a Kokoro voice is refused with a 422, as it already was on /v1/audio/speech.
GET /api/voices reports per voice whether it takes a description or a seed and what its
house description and seed are, so a client can show the controls only where they act.
The usual caveat holds and is unchanged: a seed reproduces a speaker only against the
installed MLX version. An MLX upgrade re-maps seeds to voices, so a number you liked may
not survive one.
Still open: a project cannot yet pin a description and seed in its manifest, so a project
that wants its assistant to speak as one particular designed speaker relies on each
user's Settings.
stabbur 0.11.1
Five things a headless Linux box found in 0.11.0, all fixed. If you run stabbur on a
Mac with the wizard, most of this is invisible to you; if you deploy it over SSH to a
Linux server fronting a llama-server router, all of it is for you.
serve_ui = true in stabbur.toml served the browser UI and never said so: the banner
printed the UI line only for the --ui flag. On a non-loopback bind that mattered more
than a missing line, because the tokenized URL the banner withholds is the one thing
that makes the first visit work. The page itself is not gated, so the shell loaded and
every call behind it answered 401, which looks like a broken app rather than a missing
credential. The banner now follows what is actually served.
stabbur init reported tools: none and wrote no .mcp.json, and an absent file means
"use the machine's global tools". So the project ran with tools its manifest never
mentioned, and behaved differently on every machine it was copied to. A scaffold now
always writes the file, empty when nothing was picked, and tools: none is true. An
existing project with no .mcp.json still falls back to the global set as before; the
example manifest now says so.
A project that binds no model is a supported state: serve runs free-play with the
picker. But the only non-interactive path produced a locked project, so provisioning an
unlocked one over SSH meant scaffolding it locked and hand-editing the model line out.
--no-model is the scriptable form of the wizard's "No model yet". The manifest now
leaves the model key out (commented) instead of writing model = "", and the loader
reads an empty model as unbound. That also fixes a latent bug: a wizard-made no-model
project handed serve a locked model named "".
On Linux, five of the six voice models are backed by mlx-audio, which is Apple Silicon
only, and stabbur voice list offered all six alike and invited pulling any of them.
Those rows are now dimmed and annotated, with a footnote naming the platform.
stabbur library pull voice <id> warns before downloading one; it still pulls, because a
library drive can legitimately move to a Mac. The practical consequence, now in the
voice guide as well: on Linux, text to speech works and speech to text does not, so the
chat composer's dictation mic cannot function there.
TOML binds a bare key to the table above it, so port = 8888 typed after [project]
parses cleanly as project.port, reaches nothing, and the server keeps binding 2222
while the file plainly says otherwise. The loader now warns about any key inside
[project] or [voice] that stabbur never reads there, and names the fix when the key
is a known top-level setting.
Serving a "token required" page instead of the bare UI when a token is set and the
request carries none. That is a separate design change and stays open.
stabbur 0.11.0
A project can now run its models somewhere else.
Point a project at a server
If the models already live on another box, stabbur init used to have two answers and
both were wrong: download a copy you do not need, or bind nothing at all. There is a
third now.
stabbur init mybot --upstream http://gpu-box:8080/v1 --model some-model-it-serves
The wizard has an Upstream field for the same thing. Enter asks that server what it
serves and the model list becomes those ids — offering this machine's curated downloads
for a remote project would write a name the remote probably does not have, since the
two rarely match. The download total drops to the voices, which still run locally. An
unreachable box leaves the local list alone and says so rather than emptying the
screen.
Such a project is a few kilobytes rather than a dozen gigabytes. The manifest carries
upstream = "..." and stabbur chat, stabbur serve and stabbur doctor inside it
all use the remote, while the agent loop, tools, voices and browser UI stay here.
Two fixes that came with it
stabbur chat in a project now prefers that project's upstream over the machine-wide
chat_server, below an explicit --server. Without it a remote project tried to load
a local copy of a model it deliberately does not have.
stabbur serve read --upstream only from its own flag, so in a project whose
manifest declared one it resolved the locked model against the local library and
refused to start — while chat and doctor in the same directory used the remote
quite happily. It now honors a configured upstream (a project's, or
STABBUR_UPSTREAM).
If you are upgrading
Nothing changes for a project with local models. If you set STABBUR_UPSTREAM in your
environment, note that stabbur serve now respects it without --upstream — which is
what it always looked like it did.
uv tool upgrade stabbur
stabbur 0.10.8
Documentation only. No behavior changes — upgrade if you read the docs, skip it
otherwise.
The project flow is written down
Getting started now walks what a project actually is: stabbur init for a new
directory that owns its model, voices, tools and config; uv sync for its
environment; stabbur configure to change any of it later. It says what init
downloads before you run it — roughly 12 GB with the recommended model, 5 GB with
none — that a model is optional, and that every project ships a fully documented
stabbur.example.toml.
stabbur configure had existed since 0.10.3 in the CLI reference alone, which is not
where anyone learns that a command exists. It is in the README's command list now.
The reference is complete again
stabbur benchmark has its own page but was missing from the CLI reference, so the
reference was not the full list it claims to be. Two guides — browser session auth and
the WebMCP assessment — were in the repository and in no navigation, so the built site
never linked them. Both fixed, and the completeness is now checked against the
program's own command list rather than by reading.
Corrections
The contributor notes still described project init as scaffolding into the current
directory and warning about nesting. It has created a new directory, and refused an
existing one, since 0.10.2.
uv tool upgrade stabbur
stabbur 0.10.7
Every project now ships the manual it was missing.
stabbur.example.toml
stabbur init writes a fully documented example beside the manifest: every option a
project understands, commented, with its default. stabbur never reads it — it exists so
the options are discoverable without going to the docs, which is where they were and
therefore where nobody found them.
Named stabbur.example.toml, not stabbur.toml.example, so an editor still highlights
it as TOML.
Remote backends, at last visible
This is the part worth knowing: a project has always been able to name several
OpenAI-compatible servers and run its models on them, and nothing said so anywhere a
user would look.
[[backends]]
name = "gpu-box"
url = "http://gpu-box:8080/v1"
[[backends]]
name = "lab-rig"
url = "http://lab-rig:1234"
Declare as many as you run; the name is how you pick one. stabbur's agent loop, tools
and UI stay local while the weights live on the other box. A single unnamed remote is
the shorter upstream = "http://gpu-box:8080/v1". A trailing /v1 is optional.
The example also documents the serving and runtime knobs — bind address, port, the
browser UI, an auth token, tool and confirm timeouts — and says plainly that tools do
not live in this file at all.
One thing to watch in TOML
Top-level keys must come above the first table: TOML binds a bare key to the table
above it, so a port uncommented at the foot of a file lands inside the last
[[backends]] entry and silently does nothing. The shipped example is ordered so that
uncommenting anything in place works.
If you are upgrading
Additive: an existing project is untouched, and nothing reads the new file. Copy one
into a project you already have with stabbur init in a scratch directory, or take it
from the repository.
uv tool upgrade stabbur
stabbur 0.10.6
The scaffolder now tells you what it is about to do, and takes no for an answer.
It says what it will download
A project costs about ten gigabytes, and the wizard never mentioned it — the first
honest account of the size arrived as a progress bar. The screen now carries a running
total that follows the highlighted model:
Downloads about 11.7 GB - gemma-4-12B-it-QAT-GGUF (6.7 GB) + the voices (5.0 GB)
A model is optional
"No model yet - bind one later" is the first row in the model list. The project is
still made and still gets the voices, so it can speak and transcribe on the day it is
created; stabbur configure binds a model when you have one. That is the honest answer
for weights you already keep elsewhere, or for wanting the scaffold now and the
download tonight.
The voices are not a choice
Kokoro, VoxCPM2 and Whisper come with every project — about 5 GB — including one with
no model bound. An assistant that can neither speak nor listen is not what the
scaffolder promises. --no-voices is the way out for someone who means it, and the
"Voice" kind now only tunes the system prompt, which is all it ever did.
Smaller things
.gitignore is written for every scaffolded project rather than only under --git:
what it exists to prevent — inviting you to commit six gigabytes of weights — does not
depend on whether you asked for a repository today.
If you are upgrading
Only stabbur init changes. Existing projects, the library, and free-play stabbur chat behave exactly as before.
uv tool upgrade stabbur
stabbur 0.10.5
A fix for projects made by 0.10.2 through 0.10.4: they downloaded a voice they could
not speak with.
A project can run the voices it ships
stabbur init downloads VoxCPM2 into every project it makes. The runtime that speaks
with it — mlx-audio — lives in stabbur's voice extra, and the generated
pyproject.toml did not pin it. So uv sync built an environment holding three
gigabytes of voice model that every attempt to use answered with "mlx-audio not
installed".
A project that ships voices now depends on stabbur[voice]. The extra is
platform-gated in stabbur's own metadata, so it stays a no-op off Apple Silicon, and
--no-voices still pins plain stabbur — it downloaded nothing that needs the runtime.
An existing project made by an earlier version is fixed in place with:
uv add "stabbur[voice]"
Quieter runtime rows
0.10.4 stopped the MLX rows warning when a library holds no MLX models. Every project
still warned anyway, because the voice package it downloads includes VoxCPM2, which is
an MLX build — but mlx-audio runs voice models in-process and never spawns
mlx_lm.server. Only a chat model makes those rows relevant now.
For reference: what a project costs
A default stabbur init downloads about 10 GB — the recommended model (6.7 GB) plus
the voices (3.4 GB). A voice project adds speech-to-text (1.6 GB); choosing the small
model instead brings it to about 6 GB; --no-voices leaves just the model.
uv tool upgrade stabbur
stabbur 0.10.4
Surfaces that were talking about the wrong things.
Less noise
stabbur chat announced, on every run inside a project, that it was ignoring the
machine's configured server. Running the project's own model there is the expected
thing — the header already names the model and says local — so a line explaining the
absence of a setting the project never mentions was chatter. It happens silently now.
The health report's MLX rows warned even when the library holds no MLX models, which
is most projects: a GGUF-only setup has no use for mlx-lm, and being told to install a
runtime nothing will ever spawn is a chore, not a check. Those rows now read "not
needed — no MLX models in the library". With an MLX model present the warning and its
install hint come back — a model that cannot start is exactly what the check is for.
That hint is plain prose now. It is shown verbatim in the terminal and in the browser's
health panel, neither of which renders Markdown, so its backticks and nested quotes
read as line noise and wrapped mid-token.
Voices you could not find
Kokoro is the built-in engine and its weights live at <library>/tts/kokoro rather
than as a repo, so a Voice studio built from the library scan left it out: a project
that speaks with Kokoro on the chat screen showed one model — and no way to reach the
54 built-in voices — on the voice screen. It is listed now whenever its assets are
present.
And the chat settings voice picker appended model voices after those 54 presets, a
screenful of scrolling below the fold, so a TTS model in your library read as missing.
Model voices come first now.
If you are upgrading
Nothing changes on disk or in behavior beyond what is described above.
uv tool upgrade stabbur
stabbur 0.10.3
A project is now self-contained in the way 0.10.2 claimed it was — and you can change
one after you have made it.
stabbur configure
Run it inside a project to change what stabbur init asked once, now that you know
what you are building. Four tabs:
- Assistant — the bound model (the project's own chat models, plus curated ones it
can download) and the system prompt. - Tools — the MCP servers in
.mcp.json, pre-checked, space to toggle. - Voice — the reply voice, whether the Voice surface shows at all, and which voice
models the project holds. - Library — what is on disk with sizes, selectable for removal.
Nothing is written or downloaded until you save; escape leaves the project untouched,
and a save you did not touch changes nothing. It writes stabbur.toml and .mcp.json
first and does the downloads and deletions after, so an interrupted pull cannot cost
you the settings.
A project runs its own model
A machine-wide chat_server (stabbur config set server) applied to every run,
including inside a project. So a project that had just downloaded its own copy of a
model attached to a remote instead and ran someone else's build of it — the manifest
said one thing and the session did another.
Inside a project that names a model, that default is now ignored and the project's own
model loads, saying so rather than silently. An explicit --server still attaches: the
project beats the default, not a request.
A project's tools are its own
This changes behavior. The machine-global ~/.config/stabbur/mcp.json and a
project's .mcp.json used to merge. A project whose file named three servers therefore
answered with twenty-two, and the same project answered differently on another machine,
because the extra tools came from the machine and did not travel with the directory.
A project's .mcp.json is now the whole toolset. Outside a project the machine set
applies, unchanged — that is what free-play stabbur chat runs with.
If you relied on machine-global servers inside a project, add them to that project's
.mcp.json (stabbur mcp add <name>, or the Tools tab in stabbur configure).
If you are upgrading
The tools change is the one to know about; everything else is additive. Nothing moves on
disk, and no existing model or library is touched.
uv tool upgrade stabbur
stabbur 0.10.2
stabbur init now leaves you with a project that works, rather than one that needs
a scavenger hunt first.
A new project comes with a voice
stabbur init <dir> downloads a package into the project's own library, not just the
chat model: Kokoro (the lightweight in-chat voice) and VoxCPM2 (the one worth
listening to) come with it. A Voice project adds Whisper, so the mic half of
"mic dictation in, spoken replies out" actually exists — the kind used to change the
system prompt and nothing else.
That is a few GB more per project, deliberately. --no-voices skips them for a
text-only assistant.
The model list leads with gemma-4-12B QAT, marked as the recommendation. It was
ordered by size, which made the 3B kept around for testing the default pick.
The wizard no longer asks which Kokoro voice should speak replies. Which voice speaks
is a click in the UI, not a property of the assistant; the manifest still carries a
default so a fresh project can speak immediately.
A moved project can speak
Kokoro's assets were written to the machine library, so a project carried to another
machine had nothing to synthesize with — the one thing a self-contained project is
supposed to survive. They now go to the library in play, which inside a project is the
project's own store.
VoxCPM2 has a house voice
It ships no named voices, unlike Kokoro's 54, so an unadorned request invented a new
speaker every time. The registry now pins a description and the seed that reproduces
it — chosen by ear — and that is what stabbur voice speak --model voxcpm2,
/v1/audio/speech and the chat Listen button use when nothing else is asked for.
--instruct and --seed still override it.
The pair holds only for the installed MLX version: an upgrade re-maps seeds to voices,
so a voice you liked may not survive one.
If you are upgrading
Nothing changes for an existing project or library — this is all in what init builds
and how a voice model with no presets behaves by default.
uv tool upgrade stabbur