Native Apple providers
Use macOS native OCR, file transcription, and Apple Intelligence text generation in Antfly
Antfly's opt-in apple provider uses Vision for OCR, SpeechAnalyzer for file
transcription, and Foundation Models for on-device text generation. All three
use one build flag, -Dapple-providers=true, and task-specific native APIs.
They have independent availability: working OCR or transcription does not imply
that the Apple Intelligence generation model is ready.
Build
From the repository's zig directory, use its required Zig 0.17 toolchain:
zig build antfly -Dapple-providers=true
The build requires a macOS 27 SDK / Swift 6 command-line toolchain. Vision OCR
is linked directly; generation and transcription are bundled in
lib/libantfly-apple.dylib, whose minimum macOS version is 26. The CLI and
libantfly can retain an older deployment target, for example:
zig build antfly capi -Dapple-providers=true -Dtarget=aarch64-macos.15.0
Antfly checks the running OS before loading the sidecar. On macOS below 26,
generation and transcription return AppleIntelligenceProviderUnavailable;
OCR remains independent. Older/ineligible hardware on newer macOS is checked
by the native APIs. The current validation host is macOS 27.0.1 / Apple M4 Max;
a build with a macOS 15 deployment target does not itself establish that it
launches correctly on an actual macOS 15 machine.
The flag defaults to false. Disabled and Linux builds do not compile the loader
or Swift sidecar. Metal inference is independent; add -Dmetal=false to disable
Metal for Antfly's other inference providers.
Library loading and installation
The Swift library is opened once, on the first generation/transcription call, with local symbol scope and an ABI version check. The handle and entry point remain cached for the process lifetime. Model readiness is checked separately on every generation request, so setup or an OS model update can recover without reloading the library. Failed library loads are cached; install or replace a missing/incompatible bridge and restart Antfly.
Both antfly and capi build steps install the sidecar. Keep it beside
libantfly in lib/; the CLI also finds it in its installation's lib/ directory
whether the executable is in bin/ or at the archive root. Discovery uses the
actual executable/shared-library location, including symlink resolution, and
never searches the current directory or PATH.
For a custom Lite layout, explicitly set ANTFLY_APPLE_BRIDGE_PATH to an
absolute trusted library path before starting the host. An invalid override
fails instead of falling through to other paths. Missing/unloadable and ABI
incompatible libraries return AppleNativeBridgeUnavailable and
AppleNativeBridgeIncompatible, respectively. Swift optimization follows -Doptimize (-O for release safe/fast, -Osize
for release small). The build gives the dylib an ad-hoc signature; distribution signing should include this file whenever the
CLI or Lite package is signed.
Generate text
Use this generator configuration in the existing generation endpoints or a generator enrichment:
{"provider": "apple", "max_tokens": 256, "temperature": 0.2}
Apple generation does not accept model; macOS selects its system model. Each
request creates a fresh on-device session. System instructions and alternating
user/assistant text history preserve their roles. Tools, image/audio attachments, remote endpoints,
API keys, HTTP rate limits, and other sampling options are rejected.
Availability is checked on every call. AppleModelNotReady means macOS has not
made its local model available; AppleIntelligenceDisabled and
AppleIntelligenceProviderUnavailable identify distinct states. On macOS 27,
Apple's settings are under Siri. No model download, cloud fallback, or settings
change is performed by a generation request. Context overflow and refusal are
explicit errors; output is bounded rather than silently truncated.
Transcribe recordings
Use this transcriber configuration in a transcriber enrichment:
{
"provider": "apple",
"language_code": "en-US",
"timestamps": true,
"download_assets": false
}
Apple transcription does not accept model. The locale defaults to en-US and
must be supported by the installed SpeechTranscriber runtime. Installed assets
are used without a setup download. Set download_assets: true explicitly to allow Apple's asset installer
when a requested locale is missing. Unsupported locales and missing assets have
distinct errors. Diarization and live transcription are not supported.
Audio URLs use Antfly's bounded downloader, including inline data URIs, HTTP(S), and S3 credentials supplied with the request. The default download limit is 128 MiB, which is also the adapter's maximum. Recordings must be readable by AVAudioFile and no longer than one hour. A unique temporary recording is removed when analysis ends. Responses contain final text, phrase segments, and word time ranges when requested; no confidence or speaker IDs are fabricated.
Generation and speech share one active native invocation per process. Competing
calls receive retryable AppleNativeBusy; batches execute serially. Each call
reserves a 512 MiB native workspace allowance; transcription also reserves its
bounded recording download. These are scheduling allowances, not hard limits on
Apple's model memory. Cancellation and deadlines are cooperative and retain all
borrowed buffers until the native task actually finishes.
Configure an image reader
Use this producer on an asset enrichment whose field contains a PNG or JPEG URL:
{
"type": "reader",
"config": {
"provider": "apple",
"recognition_languages": ["en-US"],
"recognition_level": "accurate",
"uses_language_correction": false
}
}
Apple OCR does not accept model; it uses Vision text recognition. Language tags
must be supported by the installed Vision runtime. recognition_level accepts
accurate or fast. The defaults are accurate recognition, English, and no
language correction. HTTP(S) and inline data:image/...;base64,... inputs use
bounded downloads with private IP blocking. Local file URLs are blocked by the
reader's default content security policy.
Plain-text output contains recognized lines. For content_type: "application/json", the reader returns its normal result array, including
regions_json: a serialized array of text, confidence, bounding boxes, and
coordinate_space: "image_pixels_top_left".
Index scanned PDFs
Use a document extraction producer to render PDF pages and feed their pixels directly to Vision. The PDF pipeline maps OCR boxes to page coordinates and retains text spans for grounding. This example creates an index over OCR chunks:
{
"num_shards": 1,
"indexes": {
"document_text": {
"type": "full_text",
"field": "text",
"artifact_name": "document_chunks",
"enrichments": [
{
"name": "document_units",
"kind": "asset",
"field": "document_url",
"content_type": "application/json",
"producer": {
"type": "document_extraction",
"config": {
"ocr": {
"enabled": true,
"executor": "reader",
"mode": "always",
"render_dpi": 150,
"prompt_policy": "plain",
"config": {
"provider": "apple",
"recognition_languages": ["en-US"]
}
}
}
}
},
{
"name": "document_chunks",
"kind": "chunk",
"field": "text",
"source_artifact_name": "document_units",
"chunk_size": 256,
"full_text_index": true
}
]
}
}
}
Send that body to POST /db/v1/tables/documents, then write documents whose
document_url points to a PDF. An inline data:application/pdf;base64,... URL
can carry a local PDF. mode: "always" forces OCR; use auto to retain the
document pipeline's text-quality fallback behavior. An Apple reader implicitly
selects the plain prompt policy when none is specified.
Limits and verification
OCR accepts empty prompts or the compatibility marker <OCR>; arbitrary
instructions and max_tokens are rejected. It recognizes text without table or
multi-column reconstruction. Image batches execute serially, preserve order and
page identity, and report serial execution. One native invocation runs at a time
per process; competing invocations receive the retryable AppleOcrBusy error.
Input limits are 16 Mi pixels per image, 64 Mi pixels per batch, eight images, 64 MiB of encoded media, and 256 MiB of raw raster data. Output defaults to an 8 MiB total response limit and fails instead of truncating. Cancellation and deadlines are cooperative; resources remain retained until Vision returns.
Each invocation reserves a 384 MiB native workspace allowance in addition to
Antfly buffers. This is scheduling admission, not a hard cap on OS model memory.
Production document budgets now scale from 256 MiB to 1 GiB with host memory;
small process envelopes can reject work with DocumentExtractionWorkingSetTooLarge.
zig build apple-bridge-loader-test lib-readers-test lib-generating-test lib-transcribing-test \
antfly-apple-provider-test apple-pdf-ocr-test \
-Dapple-providers=true -Dmetal=false -j2
zig build lib-readers-check lib-generating-check lib-transcribing-check \
-Dtarget=x86_64-linux-gnu -Dmetal=false
The native tests recognize a generated invoice image through encoded, borrowed
RGBA, and inline data URI paths. The scanned PDF qualification uses real Vision
OCR and checks exact text, page bounds, and grounding spans. They require access
to macOS Vision services; restrictive process sandboxes may prevent recognition.
The cross-build check verifies that disabled Linux readers compile without Apple
frameworks. scripts/apple-provider-probe.swift also provides an independent
Vision smoke test and can regenerate the image fixture with --write-fixture.
The speech fixture checks exact text and phrase/word timestamps. Generation tests
exercise configuration, cancellation, and the model's readiness error; when the
model is available they also check real output and its byte limit. On the macOS 27 test machine, Foundation Models initially reported
modelNotReady, then became available. Real generation, role-preserving history
recall, and output-limit enforcement passed once the OS model was ready. The standalone C driver
scripts/apple-intelligence-probe.c can query availability or exercise the same
Swift C ABI independently of Antfly.
To probe the installed Lite library from a separate C host, run from the repository
root after building capi:
xcrun clang -DANTFLY_APPLE_HOSTED_PROBE scripts/apple-intelligence-probe.c \
-o /tmp/antfly-apple-hosted-probe
ANTFLY_APPLE_HOST_LIBRARY="$PWD/zig/zig-out/lib/libantfly.dylib" \
/tmp/antfly-apple-hosted-probe
The default operation reports generation and speech availability. This exercises
sidecar discovery from libantfly, independently of the probe executable's
location. The same host probe has been qualified with real generation and file
transcription on macOS 27.