Skip to content

Berth v0.2.0

Choose a tag to compare

@github-actions github-actions released this 20 Oct 03:44
· 350 commits to main since this release
bd27ea4

v0.2.0

Berth decides who gets your GPU. Engines, games and GPU apps lease the card instead of grabbing it, so two of them never load at once and crash each other. One Go binary, no cloud account, nothing else to install.

v0.2.0 is the first release since v0.1.0. It adds four new areas: a pinned git suite for managing ComfyUI installs, a gateway with a wake plane that opens your engines' web UIs from a bookmark, a model library with pull, shelves, storage floors and CivitAI, and an overhaul of the harbor UI for phone and desktop. Windows becomes a working experimental node, and games and other apps can take the card through holds and claims.

Engine suite

  • berth engine install NAME manages a ComfyUI install as a pinned git suite: --adopt PATH records an existing checkout, --path clones a fresh one. The core, ComfyUI-Manager and each node pack are separate components, each pinned to a git commit.
  • update pins components to newer commits, keeps the old pin as the rollback snapshot, and adds node packs with --pack. rollback swaps a component back to its previous commit. remove drops the state entry, or the directory too with --delete --yes. show prints the install.
  • Update and rollback are refused while jobs run (the handoff happens at the job boundary) or when a component's tree is dirty.
  • State lives in a new engines.toml beside berth.toml. Each install derives an engine that appears in berth engine check, berth status and the gateway's wake page, and its extra_model_paths.yaml names the model roots from berth.toml. The daemon, gateway and config commands read the suite-merged config.

Gateway and wake plane

  • berth gateway serves one OpenAI-compatible port for every engine. A request naming a model an engine serves goes to that engine, and a stopped engine cold-starts under a lease: Berth drains the holder, waits, and proxies the stream.
  • The node's API key is created on first start (~/.config/berth/api.key, mode 600, printed by the new berth key), and refused when the file is group- or world-readable. Non-loopback Host names and browser origins are refused before resolution.
  • A start waits for the card no longer than --ready, and a cold start without RAM headroom is refused. berth config check rejects a model served by two engines.
  • --allow-host names a same-machine reverse proxy's hostname for a loopback gateway.
  • berth gateway --gui-listen serves /gui/<engine> for every engine that has both a start command and a gui key in berth.toml. A visit to a running engine redirects to its web UI; a stopped one shows a page that names the card's holder, shows the broker's progress behind a Start button, then opens the UI.
  • The /gui index lists every engine with its state and a launch button, and opening an engine that already answers goes straight to its UI without a start cycle.

Model library and pull

  • berth pull hf:org/repo[:quant|file|glob][@rev] resolves the revision to a commit, downloads the matching GGUF (every split part plus the vision projector) and checks each file against the size and sha256 the Hub publishes before it moves into place. Interrupted pulls resume by Range request.
  • berth verify re-hashes pulled models against their manifest with no network, and exits 1 on a missing, truncated or changed file.
  • berth models lists every model on the machine: GGUF via a built-in header reader, safetensors folders, the Hugging Face cache, LM Studio and Ollama. It shows quants, usage from the harbor's request log (--usage 30d, including a running llama-swap's resolved config) and the new SHELF column, filterable with --shelf.
  • berth models show NAME prints one model's header, and berth models export ollama writes a Modelfile and runs ollama create. --dry-run prints both; a split GGUF is refused until merged.
  • Shelves: every model lands on a shelf (chat, image, audio) from what the file states, or from a shelf declared for its root. A file that states nothing is shown unshelved, not guessed. A scan leaves a snapshot at .berth/catalog.json inside each root, so a second machine reading the same root sees the same catalog.
  • The floor: berth storage reports each root's filesystem, its free space against the [library] floor, the other operating system it shares with, and what it can share (hard links, symlinks, reflinks). A root under its floor fails the check, and a pull is refused when it would leave the root under the floor. A root whose space cannot be measured says so instead of pretending to guard.
  • CivitAI: berth pull reads a version id, a model id for its latest version, or the site's own URLs. Files land under <dir>/civitai/<model-slug>/ and are checked against the hash the site publishes. berth civitai search QUERY and berth civitai versions MODEL_ID find the ids a pull takes; public models need no key, --token-env names the variable holding one for gated results.
  • One transfer (part-file resume, size and sha256 checks, retry with backoff) serves every source, and one manifest record type covers Hub and CivitAI pulls.

Harbor UI

  • The harbor is rebuilt: sub-navigation with scroll-spy and folding panels, keyboard shortcuts with a help dialog, a log filter with live counts and jump-to-latest, dismissible alert cards, a sortable departures board, ticket copy and deep links, honest empty states, and a measured AA contrast floor. Repaint gates stop the 3 s poll rebuilding the timeline, machine and berth charts.
  • Never-started engines now read OFFLINE in grey; DOWN (UNRESPONSIVE) in amber still marks a stopped engine. The poll is quieter, accessibility gaps are closed, and the offline card is restored.
  • A new deep-water repaint: a tokenized teal-tinged dark theme, one color source for panels and charts, and a complete KPI strip.
  • Phone refresh: one 56 px rail plus a bottom nav with an active mark and a menu sheet, 44 px touch targets on every control, chip pickers and a 16 px filter field so iOS stops zooming, the departures board as cards with a wrapping log row, chart axis words moved to an HTML overlay so 2 px text never renders at 375 px, and one shape-and-word vocabulary so every state reads without colour.
  • The About tab names the navigation as it ships and lists what is still coming.

Engines and runner

  • Windows is now a working experimental node: parent and start-time attribution from the process table, berth run in its own console process group and job object so a drain stops the engine's whole process tree, a built-in claims pack that covers Steam, Epic, GOG, EA, Ubisoft, Xbox and Battle.net games by install folder, and the socket in %LOCALAPPDATA%\berth.
  • berth hold pins the card to you at the new hold priority, and berth run --pinned does the same for an app that must not be drained.
  • Claims cover work Berth does not start. The built-in pack holds the card while Steam, Lutris and gamescope games run, and tracks Blender, DaVinci Resolve, OBS and Kdenlive so their memory counts against the card instead of raising a stowaway report. [[claim]] rules in berth.toml cover the rest, by name, command line or launcher. berth claims lists the rules and what they match; berth status shows active claims and pinned leases.
  • ComfyUI drains by unload: once its queue is empty, berth run posts /free and verifies the models left VRAM. --keep-comfyui-up (with --drain-comfyui, or keep_comfyui_up on a comfyui engine in berth.toml) leaves the server running on the freed card and records the keep-up drain as an unprotected run.
  • When a waiter cannot be granted and an unprotected ComfyUI squatting on at least 1 GiB holds the card, the broker asks it for /free at its job boundary and holds the waiter until the squat drops, instead of granting the card over it.
  • A juggle guard stops two equal-priority engines draining each other, and engines rank by a configured order or by card-hours. The broker returns error codes a client can branch on.
  • A fully contested card makes the broker wait instead of granting.
  • The collisions board survives a daemon restart, and the harbor shows 5m, 15m, 1h, 24h and 7d windows.
  • The socket server now drops slow consumers with write deadlines.
  • The llama-swap patch in contrib/ wraps every model in berth run, wired in one pass; the roster lives in one README and one command.
  • A berth run with no flags reads the [[engine]] entry matching --as (or --group) for priority, needs_mib, drain settings and keep_comfyui_up. A flag set on the command line wins over the entry, and the merge is printed so file and flags can never disagree silently.
  • Kokoro-FastAPI is read and discovered on its default port (health, model list, voice count, default voice), and every engine now reports a kind.

Config

  • New keys in this release: keep_comfyui_up on a comfyui engine, the engine gui key, the engine kind key (llm, image, tts, stt, other; custom engines name their own), [library] free_floor (default 10 percent, 0 turns the guard off), [[library.root]] entries naming a root's shelf and its other OS, [[claim]] rules, and the suite's engines.toml state file.
  • Defaults are materialised in the resolved config. berth config check grows --config and --strict, and berth config show prints the resolved config in human, json, yaml or toml.

CLI

  • One command tree, one output contract (--format human, json, yaml, plus toml on config show) and one exit-code contract (0 done, 1 validation, 2 system). -v and -q apply to every command.
  • New commands since v0.1.0: gateway, key, hold, claims, pull, verify, models (with show and export ollama), storage, civitai search and civitai versions, skill install and skill show, and engine check, install, update, rollback, remove, show.
  • berth skill ships an agent skill embedded in the binary that teaches coding agents to use Berth: read the card, ask for it, holds, claims, the gateway, load failures. berth skill install writes it to ~/.claude/skills, ~/.agents/skills and ~/.config/opencode/skills (or --dir), keeping a different existing file as SKILL.md.bak.
  • berth engine check reads every configured engine once, without a daemon.
  • berth export moves its file format to --as.
  • go install and checkout builds report the module version (or the tag plus +dirty) instead of 0.1.0-dev; release builds still stamp the version.

Docs

  • The README leads with what Berth does, grouped by the command that does it, with a quick start. The support matrix and roadmap match what is merged: holds and claims are done, Windows is experimental.
  • An animated banner and a how-it-works diagram replace the old header; the first screen is shorter and the feature list moves below it.
  • README sections follow the new work: models, usage and Ollama export; the library's sources, shelves, floor and storage; the suite paragraph. Previews were re-shot from the refreshed harbor.

Upgrade notes

From v0.1.0:

  • New commands to look for: gateway, key, hold, claims, pull, verify, models, storage, civitai, skill, and the six engine suite subcommands.
  • New config keys: keep_comfyui_up, gui, kind, [library] free_floor, [[library.root]], [[claim]], and the engines.toml state file. berth config check rejects an unknown kind on a custom engine and a model served by two engines.
  • berth run with no flags now reads the matching [[engine]] entry from berth.toml; a flag you set wins, and the merge is printed. If your unit relied on the daemon's old defaults, pin the flags explicitly.
  • A pull is now refused when it would leave its destination root under [library] free_floor (default 10 percent). Set free_floor = 0 to restore the old behavior.
  • The gateway is loopback-only by default and refuses browser origins; --allow-host is the opt-in for a same-machine reverse proxy.
  • A ComfyUI drained with --drain-comfyui is unloaded through its /free endpoint and verified; a squatting ComfyUI can delay a grant while it frees.
  • The socket server drops slow consumers; a client that stops reading can now be disconnected by the daemon.
  • The harbor shows 5m/15m/1h/24h/7d windows, never-started engines read OFFLINE, and the UI was restyled end to end (deep-water theme, phone layout).
  • On a Windows node the socket lives in %LOCALAPPDATA%\berth; berth hold, --pinned and claims work there.