Dynamic voices — the ocker-bogan-nano brain¶
By default each character speaks from a static phrase bank — fast, offline, deterministic. Flip on dynamic mode and a local LLM rephrases every notification in character instead — fresh slang every time, scaled by each character's bogan/intensity and competence dials. "Build passed" becomes "yeah nice one, all green" one time and "beauty, she's a ripper" the next.
NHJ ships with its own purpose-built model for this: ocker-bogan-nano.
Why install it — the full ocker-bogan experience (everything local)¶
- Never repeats — every notification is freshly generated and scaled live to each character's bogan/competence dials, not pulled from a finite bank.
- Nails the extremes — the personas, the dials and the swearing are fine-tuned in, so the top of the dial is genuinely unhinged (Jan swears like a tradie at ockerism 11) where a static bank — or a safety-tuned general model — flattens out to a polite "oh bother".
- 100% local & private — no API key, no network, no per-notification cost; your build status never leaves the machine.
- Tiny & fast — ~940 MB, sub-second on Apple Silicon, sits resident beside the TTS voice.
What ocker-bogan-nano is¶
A ~1.5B Qwen2.5-abliterated fine-tune, distilled from a much larger abliterated teacher on thousands of in-character examples — every persona (Jan, Bazza, Karren) across the full range of dials, steeped in an Australian-slang glossary and a broad base of ocker source material. Quantised to Q4_K_M GGUF it's ~940 MB and generates a line in well under a second on Apple Silicon — small and cheap enough to keep resident alongside the TTS voice. It trains on NHJ's exact inference prompt, so the personality is baked in rather than prompted.
It's a separate model from the TTS voice — TTS turns text into Jan's sound; ocker-bogan-nano decides what she says.
How it was trained (and why it's uncensored): broad Australian is inseparable from swearing — at the top of the dial it is the grammar — so a safety-tuned model just can't produce it (ask for full ocker and you get a polite "oh bother"). ocker-bogan-nano is therefore distilled from an abliterated (refusal-removed) teacher, grounded in authentic source material — Australian Reddit threads and the gloriously unfiltered register of one-star "drunken complaints to Macca's" reviews. The uncensored register lives in the weights; NHJ then bleeps the strong words at runtime so the default experience is still safe-to-share. The full pipeline, the abliteration rationale and the data provenance are documented on the ocker-bogan-nano model card.
Install it¶
That downloads ocker-bogan-nano from Hugging Face, points .env at a local OpenAI-compatible server, and installs a LaunchAgent so the endpoint (http://127.0.0.1:9991/v1) is always running. Then check it:
Runs cross-platform via llama.cpp — Linux/Windows/Mac, CPU or GPU.
Manual / advanced
# download the Q4_K_M GGUF (~940 MB) yourself …
hf download guruswami-ai/ocker-bogan-nano ocker-bogan-nano-Q4_K_M.gguf \
--local-dir "$HOME/Library/Caches/not-happy-jan/ocker-bogan-nano"
# … serve it with llama.cpp (or use the LaunchAgent in ../integrations/launchd/) …
llama-server -m "$HOME/Library/Caches/not-happy-jan/ocker-bogan-nano/ocker-bogan-nano-Q4_K_M.gguf" \
--alias ocker-bogan-nano --host 127.0.0.1 --port 9991 -c 2048
Bring your own model instead¶
ocker-bogan-nano is just the default. Dynamic mode speaks plain OpenAI /chat/completions, so you can point it at anything — a bigger local model (Ollama, LM Studio, vLLM, lightning-mlx) or a cloud API (OpenAI, Groq, OpenRouter):
# .env — e.g. Ollama
NHJ_DYNAMIC=1
NHJ_DYNAMIC_BASE_URL=http://localhost:11434/v1
NHJ_DYNAMIC_MODEL=qwen2.5:7b-instruct
The character's persona, dial and swearing setting become the system prompt, so even a small general instruct model does a decent job — ocker-bogan-nano just does it better and cheaper because the personas are fine-tuned in. If the endpoint is ever unreachable, NHJ silently falls back to the static banks, so dynamic is always safe to enable.
Swearing & the bleep¶
At ockerism 11 Jan swears like a true bogan. The strong words are bleeped by default — replaced with a spoken "quack" — so it's safe to share, and funnier ("get absolutely quacked, ya legend"). The same filter cleans up anything a dynamic model generates.