Repository navigation
v1.4.0 - 2026-09-08
Release Notes
Downloads stop belonging to the terminal that started them. A pull now runs in a worker process of its own, is managed under hedos pull from anywhere, and has a screen of its own in the shelf. The rest of the release is what end-to-end testing turned up once a model could be pulled and then run in the same sitting: pulled models that no runtime would bid for, sizes that read a unit low, and a handful of places where the interface said one thing while the machine did another.
- A pull outlives its terminal.
hedos pull <ref>hands the download to a detached worker and follows it, Ctrl-C detaches instead of cancelling, and-dreturns straight away. Each job is a directory under the data dir holding its descriptor, live record, history, the lock a running worker holds, and a control file for asks; liveness is that lock rather than a pid, so a worker killed while the machine slept is known to be gone instead of being waited on forever. The worker scans the store when it finishes, so the model reaches the shelf whether anything is watching or not. - Seven subcommands under the one verb:
hedos pull ls | attach | pause | resume [--all] | cancel | logs | clean, each honouring--json. A job is named by its id, an unambiguous prefix of one, or its reference; a name several pulls answer to means the one still going. Since a bare word is a valid Ollama tag, a model named after a subcommand is writtenhedos pull -- ls. - Pulls join and resume. Two terminals pulling the same model in the same instant share one download instead of the second failing as a duplicate; a pull that stopped part-way carries on from the bytes already on disk; a transfer that breaks retries with a growing pause inside
pull.retry_window_minutesbefore it is left interrupted for you. A worker that died is picked back up the next time the shelf opens (pull.auto_resume, on by default), and pulling the model again always carries a stopped pull on, while a pull you paused stays paused until you say otherwise. [pull]inhedos.toml:max_concurrent(a slot pool held across terminals, with a queued pull saying it is waiting for a free slot rather than reading as one nobody came for),auto_resume,partial_age_hours,retry_window_minutes, andkeep_ended.- The shelf's task strip is a view over the job directory rather than over its own memory, so it shows pulls this screen never started and quitting no longer waits on a download.
copens a stop card that offerspto pause, keeping every byte that landed, orxto cancel, naming what has already arrived instead of acting on the spot;Rresumes a stopped pull; a row dismissed withdstays dismissed between runs. Popens a pulls screen in the shelf's place: every pull the store holds, newest first, with the selected one's record, rate, estimate, and history beside it.c,R,Y,x, andpstop, resume, copy the id, forget an ended record, and start a new pull.yandYcopy throughpbcopywhere there is one, falling back to OSC 52.- Models pulled from Hugging Face run. Identification looked inside a repo directory only for a diffusers index or a config with safetensors beside it, so a repo of GGUF weights came back unknown, no runtime bid for it, and
hedos runsaid the model had no runtime for chat. The weights are read now, including in a repo that keeps a directory per quantization, and one rule picks the file a server is handed for both the scanner and identification, which used to walk the same directories by different rules: the largest set that could actually be loaded, hidden leftovers and directories wearing a weight's name skipped, a sharded set answered through the first file beside it. Models pulled before this resolve on the next scan; nothing needs pulling again. - The GGUF architecture table knows the encoders that only embed (
nomic-bert-moe,jina-bert-v2,jina-bert-v3,neo-bert,modern-bert,eurobert,gemma-embedding,llama-embed,t5encoder), the newer models that can also see (qwen3vl,qwen3vlmoe,cogvlm,hunyuan-vl), and the vocoder half of a speech pair (wavtokenizer-dec), which serves nothing on its own. What a header says is final, an empty capability list included, so a projector no longer listschatit cannot do, and a model claims sight only when its image encoder is on disk beside it. - Hugging Face downloads are verified again. The hub lists a file's hash as
lfs.sha256, which the client now reads; it readlfs.oid, which the hub does not send, so no download had a hash to check against and a corrupted partial was registered rather than failed. A download that had already landed every byte is also no longer thrown away and fetched again: resuming asked for a range beginning at the end of a whole file, which a server answers 416 and the resume path read as a partial past the end, so a stream that errored after its last chunk cost the entire file, over and over across the retry window. - A failed pull says what actually happened. A repo the hub refuses to list reads as not found or private instead of gated; with a token attached a 403 says the token lacks access and a 401 says the token was rejected; an error from this machine, such as a directory that cannot be written, fails the pull on the first attempt instead of being retried as though the network had dropped; the disk-headroom check measures the volume the model will be written to rather than the directory the command was typed in; and
hedos pull <ref>now exits non-zero when the pull was interrupted, sohedos pull X && hedos run Xno longer runs weights that were never fetched. A pause or a cancel you asked for still exits 0. - Sizes are exact, and stated in the units the hubs state them in. The record kept a model's size in whole mebibytes and every reader expanded it again as decimal, so a 491,400,032-byte model read
490 MBwhile the pull that fetched it said491 MB, and anything under a mebibyte read as unknown;hedos rmand a pull's confirmation now say4.3 GBwhere they said~4294 MB. A shelf written before this keeps its figures, folded into the exact ones as the registry loads, with no rescan to wait for. - A model whose weights are gone stops reading as though it could run.
hedos lsmarks the row✕and its fit column readsgone, the word the shelf already used;run,chat,warmand the rest refuse it with that reason instead of failing later about whatever the missing files broke;hedos rmstill reaches it, which is what removal is for. HF_HOMEandHF_HUB_CACHEname the machine's one hub cache instead of adding a second. Discovery swept both the environment's cache and~/.cache/huggingface/hubwhile a pull wrote only to the first, so the two could come apart; both resolve the root the same way now, which is the rule the hub's own tooling follows. Models left in the default cache whileHF_HOMEpoints elsewhere read as gone on the next scan; add that path tohf_cache_rootsto keep sweeping both.- A model declaring a context window under 512 tokens can be run. The budget held back a flat 256 tokens for the reply before it looked at the prompt, so a 128-token model was refused everything it was ever asked; a window that cannot afford that floor now keeps half of itself for the reply. At 512 tokens and above nothing changes.
- A chat reply whose characters are wider than one byte, in Georgian, Chinese, or emoji, no longer crashes the shelf, and reading the environment no longer panics on a variable this process cannot read as text.
Install hedos 1.4.0
Install prebuilt binaries via Homebrew
brew install theiskaa/tap/hedosDownload hedos 1.4.0
| File | Platform | Checksum |
|---|---|---|
| hedos-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| hedos-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| hedos-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| hedos-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |