What
Add Apple's Foundation Models framework (iOS 26+) as a provider option in the AI Coach
settings, alongside the existing OpenAI-compatible ones. Selecting it would run the coach
entirely on-device: no base URL, no API key, no network call, nothing leaving the phone.
Why this is worth the work
The coach is the one part of the app that requires either a paid API key or a self-hosted
server. Everything else is free and local by default. This closes that gap for iOS 26 users.
It also removes a network egress path. PRIVACY.md is careful to list the BYOK assistant as one
of the few things that sends health data off the device, with the honest warning that "the
prompts contain your health data." An on-device provider makes that warning unnecessary for the
people who choose it.
It works, I measured it
I couldn't call the framework directly from another app, because iOS suspends a backgrounded
server process and app-to-app localhost serving is a dead end. So I tested Apple's model
through the OpenAI shim in the App Store app "Local LLM Server", from a
Mac on the same LAN, on an iPhone 17 Pro / iOS 26:
- Tool call emission: correct. Returned a well-formed
tool_calls object with a valid
function name and JSON arguments, from a tools array supplied in the request.
- Second turn: correct. Given the tool result, it produced a coherent answer that used the
actual returned values.
- Latency for that two-turn loop: 1.4 seconds.
For comparison, on the same day I benchmarked qwen2.5:7b-instruct-q4_K_M on a self-hosted
mini-PC and got 23.5s per turn, which put a multi-tool coach question past this app's 120s
client timeout. On-device was roughly thirty times faster than that, free, and never left the
phone.
Why it fits this project's rules specifically
Foundation Models does guided generation. Tool schemas are enforced at the token-sampling
level, so the model structurally cannot emit malformed JSON for a declared tool. That is a
better guarantee than an unconstrained GGUF model gives, and it sits well with the project's
"never fabricate a number" rule.
Anecdotally relevant: I tested qwen2.5:3b as a cheap local coach and it invented a recovery
percentage that was nowhere in the tool output, and twice described an elevated resting heart
rate as being below baseline. Constrained decoding does not fix reasoning, but it does remove
the malformed-output class of failure entirely.
Scope
As I read the tree this lands in lib/ai/ as an additional provider, plus a platform-channel
bridge to a small Swift shim calling LanguageModelSession with GenerationSchema built from
the existing tool definitions. Nothing in protocol or analytics is touched, and no existing
provider changes. Android and older iOS are unaffected. The option would only appear where the
framework is available and Apple Intelligence is enabled.
Honest limitations
- iOS 26+ only, and only where Apple Intelligence is enabled and the model has downloaded.
- The on-device model is roughly 3B. Expect weaker reasoning than a frontier API model. This
should be presented as the free/private option, not the best one.
- What I could not test: a real multi-tool agentic loop of the shape this app's coach
actually runs. My test was two turns with a single tool. Longer loops and how it handles
several tools in one request are unknown to me.
- I also have not verified how the framework behaves under memory pressure while the app is
also holding a BLE connection and the local database.
Prior art
I searched issues and PRs across edge, analytics, protocol and backend for foundation
models, Apple Intelligence, CoreML, MLX, on-device LLM. I found nothing, so apologies if this
has been discussed somewhere I did not look, Discord for instance.
Offer
Happy to implement this if you want it. Asking first, per CONTRIBUTING, rather than arriving
with an unsolicited PR of this size. If you would rather not take on an Apple-specific
dependency, or it conflicts with the F-Droid / dependency-isolation direction in #321, that is
a completely reasonable no and I would rather hear it now.
What
Add Apple's Foundation Models framework (iOS 26+) as a provider option in the AI Coach
settings, alongside the existing OpenAI-compatible ones. Selecting it would run the coach
entirely on-device: no base URL, no API key, no network call, nothing leaving the phone.
Why this is worth the work
The coach is the one part of the app that requires either a paid API key or a self-hosted
server. Everything else is free and local by default. This closes that gap for iOS 26 users.
It also removes a network egress path. PRIVACY.md is careful to list the BYOK assistant as one
of the few things that sends health data off the device, with the honest warning that "the
prompts contain your health data." An on-device provider makes that warning unnecessary for the
people who choose it.
It works, I measured it
I couldn't call the framework directly from another app, because iOS suspends a backgrounded
server process and app-to-app localhost serving is a dead end. So I tested Apple's model
through the OpenAI shim in the App Store app "Local LLM Server", from a
Mac on the same LAN, on an iPhone 17 Pro / iOS 26:
tool_callsobject with a validfunction name and JSON arguments, from a tools array supplied in the request.
actual returned values.
For comparison, on the same day I benchmarked
qwen2.5:7b-instruct-q4_K_Mon a self-hostedmini-PC and got 23.5s per turn, which put a multi-tool coach question past this app's 120s
client timeout. On-device was roughly thirty times faster than that, free, and never left the
phone.
Why it fits this project's rules specifically
Foundation Models does guided generation. Tool schemas are enforced at the token-sampling
level, so the model structurally cannot emit malformed JSON for a declared tool. That is a
better guarantee than an unconstrained GGUF model gives, and it sits well with the project's
"never fabricate a number" rule.
Anecdotally relevant: I tested
qwen2.5:3bas a cheap local coach and it invented a recoverypercentage that was nowhere in the tool output, and twice described an elevated resting heart
rate as being below baseline. Constrained decoding does not fix reasoning, but it does remove
the malformed-output class of failure entirely.
Scope
As I read the tree this lands in
lib/ai/as an additional provider, plus a platform-channelbridge to a small Swift shim calling
LanguageModelSessionwithGenerationSchemabuilt fromthe existing tool definitions. Nothing in
protocoloranalyticsis touched, and no existingprovider changes. Android and older iOS are unaffected. The option would only appear where the
framework is available and Apple Intelligence is enabled.
Honest limitations
should be presented as the free/private option, not the best one.
actually runs. My test was two turns with a single tool. Longer loops and how it handles
several tools in one request are unknown to me.
also holding a BLE connection and the local database.
Prior art
I searched issues and PRs across
edge,analytics,protocolandbackendfor foundationmodels, Apple Intelligence, CoreML, MLX, on-device LLM. I found nothing, so apologies if this
has been discussed somewhere I did not look, Discord for instance.
Offer
Happy to implement this if you want it. Asking first, per CONTRIBUTING, rather than arriving
with an unsolicited PR of this size. If you would rather not take on an Apple-specific
dependency, or it conflicts with the F-Droid / dependency-isolation direction in #321, that is
a completely reasonable no and I would rather hear it now.