The anchored ops end to end. Point it at a voice memo and one audio file becomes a
transcript, a cleaned-up text, a one-line summary, typed action items, a Japanese
translation, and a spoken reply (speech.wav); point it at an image and it is captioned,
object-detected, and OCR’d — all on device. No sessions, no prompts, no model names in
app code: ops are the stable API and the kit resolves a catalog model behind them.
swift run OpsDemo # text + search ops on built-in samples (qwen3 4B + EmbeddingGemma)
swift run OpsDemo voice-memo.wav # speech -> text -> speech (downloads Whisper + VoxCPM once)
swift run OpsDemo photo.jpg # caption + detect + read (Qwen3-VL 2B, RF-DETR, GLM-OCR)
swift run OpsDemo transcript.txt # raw ASR transcript -> written text (S1-mini, chunked)
The memo path cleans the transcript with CoreAI.tidyTranscript, not proofread: the input
is raw dictation, and the op for that position drops fillers and false starts and writes
spoken numbers and dates out — which proofread is contracted not to do.
A .txt / .md argument runs that op alone, which is where long input is worth watching. A
695-token meeting transcript is cut into word-boundary chunks and stitched (13.6 s on an M4
Max), because on iPhone the engine caps prompt + generated at 1024 tokens:
> CoreAI.tidyTranscript(raw) [3480 characters in]
[clean] Okay, let me just get all of this down before I forget it. We had the quarterly
review this morning, and there were basically three things that came out of it.
First, the pipeline numbers are actually better than we thought. We closed 19 deals in Q3,
not 17. The discrepancy was two deals that got booked on October 1 instead of September 30.
…
Real pipeline output (Mac, ~38 s warm for the five text ops):
> CoreAI.transcribe(memo)
[transcript] Team meeting notes. Please ship 12 units of the Alpha widget to the Osaka
office by Friday. Also, schedule a follow-up call with Dana next Tuesday to review the
launch plan.
> CoreAI.summarize(clean, style: .oneLine)
[summary] Ship 12 Alpha widgets to the Osaka office by Friday and schedule a follow-up
call with Dana next Tuesday to review the launch plan.
> CoreAI.extract(clean, as: ActionItems.self)
[task] Please ship 12 units of the Alpha widget to the Osaka office by Friday.
[task] Schedule a follow-up call with Dana next Tuesday to review the launch plan.
> CoreAI.translate(clean, to: .japanese)
[ja] チーム会議のメモ。12個のアルファウィジェットを大阪支社に金曜日までに発送してください。…
> CoreAI.speak(summary)
[audio] 8.4 s -> speech.wav
extract shapes the reply with the @Generable type’s generation schema and parses it
back through the framework, so the demo’s ActionItems / Order types are exactly what
you would write for Apple’s respond(generating:). Override any op’s model per call,
e.g. options: .model("qwen3-0.6b") when speed matters more than fidelity, or
options: .model("mineru2.5-pro") to swap the OCR engine behind read.