macbook-ai
Python interface to macOS AI capabilities — speech recognition, text-to-speech, and LLM via Apple Foundation Models.
All processing is on-device. No API keys, no network calls.
Requirements
- macOS 10.15 or later
- Python 3.10 or later
- The first time you use Speech-to-Text, macOS will prompt for access. You may need to enable it manually: System Settings > Privacy & Security > Speech Recognition > Terminal
Installation
pip install macbook-ai
With uv:
uv add macbook-ai
Note: Foundation Models require macOS 15.6+ and pyobjc-framework-FoundationModels (install separately when available on PyPI).
Features
Speech-to-Text (STT)
Powered by the macOS SFSpeechRecognizer framework.
Grant Permission
The first time you use recognition, macOS will prompt for access. You can trigger it explicitly:
from macbook_ai.stt import SpeechRecognizer
status = SpeechRecognizer.request_authorization()
# Returns: 'authorized' | 'denied' | 'restricted' | 'not_determined'
If running from Terminal, you may need to enable it manually: System Settings > Privacy & Security > Speech Recognition > Terminal
Transcribe Audio Files
from macbook_ai.stt import SpeechRecognizer
recognizer = SpeechRecognizer() # defaults to en-US
text = recognizer.recognize_file("recording.m4a")
print(text)
Async Support
import asyncio
from macbook_ai.stt import SpeechRecognizer
async def main():
recognizer = SpeechRecognizer()
text = await recognizer.recognize_file_async("recording.m4a")
print(text)
asyncio.run(main())
Multiple Languages
recognizer = SpeechRecognizer(locale="fr-FR")
recognizer = SpeechRecognizer(locale="es-ES")
recognizer = SpeechRecognizer(locale="ja-JP")
Supported Audio Formats
Any format supported by AVFoundation: WAV, M4A, MP3, AIFF, CAF, FLAC, and more.
Error Handling
from macbook_ai.stt import SpeechRecognizer
from macbook_ai._exceptions import AuthorizationError, RecognitionError
recognizer = SpeechRecognizer()
try:
text = recognizer.recognize_file("recording.m4a")
except AuthorizationError:
print("Grant Speech Recognition access in System Settings first.")
except RecognitionError as e:
print(f"Recognition failed: {e}")
except TimeoutError:
print("Recognition timed out — try a shorter clip or increase timeout.")
Text-to-Speech (TTS)
Powered by the macOS AVSpeechSynthesizer framework.
Basic Usage
from macbook_ai.tts import SpeechSynthesizer
synth = SpeechSynthesizer()
synth.speak("Hello from macbook-ai")
Async Support
import asyncio
from macbook_ai.tts import SpeechSynthesizer
async def main():
synth = SpeechSynthesizer()
await synth.speak_async("Hello from macbook-ai")
asyncio.run(main())
Custom Voices and Settings
# List available voices
voices = SpeechSynthesizer.available_voices(language="en")
for voice in voices:
print(f"{voice['name']} ({voice['identifier']})")
# Use a specific voice
synth = SpeechSynthesizer(
voice="com.apple.voice.compact.en-US.Samantha",
rate=0.5, # 0.0 (slowest) to 1.0 (fastest)
volume=1.0 # 0.0 to 1.0
)
synth.speak("Hello in Samantha's voice")
Save to Audio File
synth = SpeechSynthesizer()
synth.save_to_file("Hello world", "output.caf")
Apple Foundation Models (macOS 15.6+)
On-device language model — no API keys, no network calls.
Note: Requires macOS 15.6+ and pyobjc-framework-FoundationModels (not yet on PyPI).
Basic Usage
import asyncio
from macbook_ai.foundation import LanguageModel
async def main():
model = LanguageModel()
# Get complete response
response = await model.respond("What is the capital of France?")
print(response)
asyncio.run(main())
Streaming Responses
import asyncio
from macbook_ai.foundation import LanguageModel
async def main():
model = LanguageModel()
async for chunk in model.stream("Write a haiku about Python"):
print(chunk, end="", flush=True)
asyncio.run(main())
With System Instructions
model = LanguageModel(instructions="You are a helpful coding assistant.")
response = await model.respond("Explain list comprehensions")
print(response)
Development
Running Tests
uv run pytest tests/ -v
License
MIT
Release files for macbook-ai 0.1.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| macbook_ai-0.1.9.tar.gz | 28.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| macbook_ai-0.1.9-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 38.5 kB
Release files / macbook_ai-0.1.9.tar.gz
| Download URL | macbook_ai-0.1.9.tar.gz |
|---|---|
| Size | 28.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
009158ba7c52b8980f7e089206746dbbab4d7877430f0d53f24b893704e56d40
|
|
BLAKE2b-256 checksum How to use checksums |
7d5a57addba0ef1672bce5d15afd6965241ae21e9b0256699a1cbb2fbdb8a9d5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.
Transparency logRelease files / macbook_ai-0.1.9-py3-none-any.whl
| Download URL | macbook_ai-0.1.9-py3-none-any.whl |
|---|---|
| Size | 10.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e7ebe1a623329e4e3837bd35b9ad9075b0818d1478365e3f99753b328a64b3a1
|
|
BLAKE2b-256 checksum How to use checksums |
3661c7002569811da781c5f432d8f7ed47a3bfe30e2eeee9f1b8872b13a6137d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.
Transparency log