feat(ai-providers): add Apple Intelligence on-device provider for macOS 26+#1554
feat(ai-providers): add Apple Intelligence on-device provider for macOS 26+#1554datlechin wants to merge 2 commits into
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3667d72492
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| static func makeAppleIntelligenceProvider() -> ChatTransport { | ||
| let status = AppleIntelligenceAvailability.currentStatus() | ||
| if #available(macOS 26, *), status == .available { | ||
| return AppleIntelligenceTransport() |
There was a problem hiding this comment.
Guard the FoundationModels-only transport reference
When this target is built with an SDK where canImport(FoundationModels) is false, AppleIntelligenceTransport is compiled out by the #if in its own file, but this factory still references it. The weak-link flags do not help when the SDK module is unavailable, so pre-Xcode 26 builds fail instead of falling back to UnavailableTransport; wrap this branch in #if canImport(FoundationModels) and return the unavailable transport otherwise.
Useful? React with 👍 / 👎.
…nd share the System Settings opener
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 13e297c8e2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if #available(macOS 26, *), status == .available { | ||
| return AppleIntelligenceTransport() | ||
| } | ||
| return UnavailableTransport(reason: status.statusText) |
There was a problem hiding this comment.
Avoid caching the unavailable Apple transport
If an existing Apple Intelligence provider is resolved while currentStatus() is transiently unavailable, such as .modelNotReady during the model download, this branch returns an UnavailableTransport; createProvider then caches that transport for the config, so later chats keep failing even after the model becomes available unless the app restarts or the provider settings change. Make this status-dependent fallback bypass the provider cache or invalidate it when availability changes.
Useful? React with 👍 / 👎.
Closes #1048.
Adds Apple Intelligence as an on-device AI chat provider on macOS 26 and later, backed by the Foundation Models framework. No API key, no network: schema and queries stay on the Mac. The app's macOS 14.0 minimum does not change; everything is gated behind
#available(macOS 26, *)andFoundationModelsis weak-linked.What it does
AppleIntelligenceTransport: ChatTransportoverLanguageModelSession. It flows through the existing registry, factory, and transport pipeline as a realAIProviderConfig(type: .appleIntelligence, new.deviceauth style), so the model picker, per-turn attribution, and persistence work with no special-casing.How the hard parts work
streamResponseyields cumulative snapshots, so the transport diffs each against the previous (with a prefix guard) to emit text deltas.Tool.ArgumentsisGeneratedContentand theGenerationSchemais built at runtime from ourJsonValueviaDynamicGenerationSchema. The framework runs the tool loop itself; eachTool.callbridges to the existing approval and execution path throughtoolInvocationRequestand a reply token.AppleIntelligenceStatusfacade wraps the#availableandSystemLanguageModel.default.availabilitycheck so the un-gated UI can read availability without importing the framework.Transcriptfrom the conversation each call, so it needs no reset wiring.The generic Copilot tool-dispatch functions were renamed to provider-neutral names since this transport reuses them.
Tests
New tests cover the availability facade mapping, the schema bridge, seeding idempotency and no-override, and the factory guard (an Apple Intelligence config never falls back to an OpenAI-compatible transport). Foundation Models tests are gated to macOS 26.
Before merge
Transcriptinitializers inAppleIntelligenceTransport.buildTranscriptwere written against Apple's docs but not compiled here.com.apple.Siri-Settings.extension) is inferred; it falls back to the Settings root if the identifier is wrong. Worth confirming on a real macOS 26 machine.