Repository navigation
hive/apple-fm: Apple's on-device model as a nurse - #71
Merged
Merged
Conversation
A sibling of ollama-worker that runs Apple's on-device 3B FoundationModel via FoundationModels — a local, network-free, key-free LLM. Registers with humd over thrum, advertises model `apple-3b-on-device`, and turns chi:"prompt" into chunk/finish tones. The Rust side (src/) mirrors ollama-worker but, instead of HTTP to Ollama, shells out to a small Swift bridge (bridge/gen) that wraps FoundationModels and streams NDJSON deltas. The only Apple-specific code in the tree is bridge/gen.swift (+ probe.swift); no Apple symbols enter the Rust side, and the bridge is mac-gated. On boot a capability probe keeps the hive present-but-dormant when Apple Intelligence isn't available. Isolated prototype — verified in isolation on macOS 26 (M5 Max): probe reports available, real on-device deltas stream, and the Rust worker compiles + connects to a live humd advertising the model. Not yet co-installed into the mac desktop bundle.
…file Rebuilds the apple-fm-worker prototype on main's nurse model as hives/apple-fm. apple-fm-nurse (Rust, on hum-nest's serve_nurse) runs apple-fm-gen, a Swift bridge to FoundationModels, once per bloom: the prompt's system prompt becomes Apple's instructions, its graft (or the turns its cell grew, for a forager that sends only new words) becomes the transcript, and temperature/season/prune/seed become Apple's generation options. Deltas unfurl as they come, each only the new words; the bloom wilts stop or max_tokens with Apple's token counts as nectar. frost is held by the nurse, which kills the bridge at a stop; a cancel kills it too. Pollen and trellis are refused rather than grown as if absent. Before nestling it probes the bridge: it waits unnestled while Apple Intelligence is off or its model downloads, exits 0 on a Mac that cannot run it (its unit stays down), and fails on a bridge that cannot run. Fixes in the prototype: the bridge's stdout was never piped, --probe was ignored by the Swift side, cumulative snapshots were sent as deltas, a duplicate fn broke non-mac builds, the cell's exit sender was dropped at birth, a cancel left the bridge running, and the graft never reached the model. Tests: unit and cell tests against a stand-in bridge; E2E through a real humd (prompt, kept conversation, cancel, dormant-then-ready, never, missing bridge); and an ignored live test against Apple's model. Registered in the workspace exclude list, release.sh's lockstep, and the hives catalogue.
…rom its newest turns Apple's model has a 4096-token context, and a cell that remembers its sigil's turns would otherwise fail every prompt once the conversation outgrew it. The bridge now counts tokens (macOS 26.4+) and keeps the newest turns that leave room for the reply (its season, else 1024 tokens), reporting how many it dropped in its finish; the cell forgets the same turns. A reply with no season is held to the room left, so it wilts max_tokens instead of overflowing mid-stream, and the finish carries the bridge's own reason. Before 26.4 the bridge drops the older half of the turns whenever Apple refuses the transcript. The cell no longer waits on a bridge that lingers after its finish or error: it kills it. Tests cover the dropped turns, the bridge's reason, a lingering bridge, and, live, a conversation past the context.
…fits its context A bridge that closed its stdout but lived on held its cell's next prompt forever while the nurse waited on it; the nurse now gives it two seconds and kills it, telling the bloom apple_fm_bridge_died. And a season larger than the room the conversation left is held to that room too, so no reply overflows the model's context mid-stream.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
hive/apple-fm: Apple's on-device model as a nurse
hives/apple-fmruns Apple's on-device foundation model (SystemLanguageModel.default, ~3B, 4096-token context) as a hum nurse: local, network-free, key-free. It advertisesapple-3b-on-device.This supersedes the Oct 18
apple-fm-workerprototype, which predates main's move from WorkerBee to Nurse (chunk/finish→unfurl/wilt,serve_worker→serve_nurse, signed bee entry,hive-installunits, version lockstep) and could not compile against main. It is rebuilt on main, andhives/apple-fm-workeris removed.Shape
apple-fm-nurse(Rust, onhum-nest'sserve_nurse) runsapple-fm-genonce per bloom.apple-fm-genis a Swift bridge built frombridge/gen.swift, the only file in hum that imports an Apple framework. The Rust side holds no Apple symbols and builds anywhere;./buildrefuses any host that isn't an Apple silicon Mac.temperature/season/prune/seedbecome Apple's generation options;temperature: 0samples greedilyfrost(stop sequences) is held by the nurse, which kills the bridge at a stopstopormax_tokenswith Apple's token counts as nectar.apple-fm.trimmed.apple_fm_words_only;trellis→apple_fm_no_trellisapple_fm_<reason>apple_fm_bridge_diedBugs in the prototype, fixed
--probewas ignored by the Swift side, so the probe always reported "available".resolve_bridgebroke non-mac builds.Tests (
cd hives/apple-fm && cargo test)Frostacross delta boundaries, history kept and overridden by graft, dropped turns forgotten, still/cancel killing the bridge, stops,max_tokens, and a bridge that errors, dies, lingers, or goes silent../build && cargo test --test live -- --ignored): conversation memory, real streaming with no repeated text, stop sequence,max_tokensat exactly the season, a conversation longer than the context, and cancel.Verified on a live humd
Installed with
hum hive ./hives/apple-fm install(orchd → launchd unithum-apple-fm.apple-fm) and exercised throughopenai-server's/v1/chat/completions:max_tokens→lengthstopAlso checked against the real model:
maxCells)Registered
Cargo.tomlexclude listrelease.shversion lockstep (0.34.1)hives/README.mdcatalogueNot in this PR
Co-installation into the mac desktop bundle: the follow-up gate.Struck: there is no mac desktop bundle; after merge, apple-fm is a bundled hive any capable Mac installs withhum hive apple-fm install.Note: wire.yml builds no hives, so CI doesn't exercise this hive. The tests above were run locally.