apple-foundation-models 0.1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of apple-foundation-models might be problematic. Click here for more details.
- apple_foundation_models-0.1.3/LICENSE +21 -0
- apple_foundation_models-0.1.3/MANIFEST.in +27 -0
- apple_foundation_models-0.1.3/PKG-INFO +446 -0
- apple_foundation_models-0.1.3/README.md +410 -0
- apple_foundation_models-0.1.3/apple_foundation_models.egg-info/PKG-INFO +446 -0
- apple_foundation_models-0.1.3/apple_foundation_models.egg-info/SOURCES.txt +26 -0
- apple_foundation_models-0.1.3/apple_foundation_models.egg-info/dependency_links.txt +1 -0
- apple_foundation_models-0.1.3/apple_foundation_models.egg-info/requires.txt +7 -0
- apple_foundation_models-0.1.3/apple_foundation_models.egg-info/top_level.txt +1 -0
- apple_foundation_models-0.1.3/applefoundationmodels/__init__.py +108 -0
- apple_foundation_models-0.1.3/applefoundationmodels/_foundationmodels.c +13192 -0
- apple_foundation_models-0.1.3/applefoundationmodels/_foundationmodels.pxd +70 -0
- apple_foundation_models-0.1.3/applefoundationmodels/_foundationmodels.pyx +407 -0
- apple_foundation_models-0.1.3/applefoundationmodels/base.py +36 -0
- apple_foundation_models-0.1.3/applefoundationmodels/client.py +203 -0
- apple_foundation_models-0.1.3/applefoundationmodels/constants.py +30 -0
- apple_foundation_models-0.1.3/applefoundationmodels/exceptions.py +115 -0
- apple_foundation_models-0.1.3/applefoundationmodels/py.typed +2 -0
- apple_foundation_models-0.1.3/applefoundationmodels/session.py +235 -0
- apple_foundation_models-0.1.3/applefoundationmodels/swift/foundation_models.h +58 -0
- apple_foundation_models-0.1.3/applefoundationmodels/swift/foundation_models.swift +371 -0
- apple_foundation_models-0.1.3/applefoundationmodels/types.py +124 -0
- apple_foundation_models-0.1.3/pyproject.toml +64 -0
- apple_foundation_models-0.1.3/setup.cfg +4 -0
- apple_foundation_models-0.1.3/setup.py +154 -0
- apple_foundation_models-0.1.3/tests/test_client.py +146 -0
- apple_foundation_models-0.1.3/tests/test_integration.py +384 -0
- apple_foundation_models-0.1.3/tests/test_session.py +163 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Benjamin Tucker
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Include all necessary files in source distribution
|
|
2
|
+
|
|
3
|
+
# Swift source files
|
|
4
|
+
include applefoundationmodels/swift/*.swift
|
|
5
|
+
include applefoundationmodels/swift/*.h
|
|
6
|
+
|
|
7
|
+
# Dynamic library
|
|
8
|
+
include lib/*.dylib
|
|
9
|
+
include lib/*.swiftmodule
|
|
10
|
+
|
|
11
|
+
# Cython source files
|
|
12
|
+
include applefoundationmodels/*.pyx
|
|
13
|
+
include applefoundationmodels/*.pxd
|
|
14
|
+
|
|
15
|
+
# Type stub marker
|
|
16
|
+
include applefoundationmodels/py.typed
|
|
17
|
+
|
|
18
|
+
# Documentation
|
|
19
|
+
include README.md
|
|
20
|
+
include LICENSE
|
|
21
|
+
|
|
22
|
+
# Exclude unnecessary files
|
|
23
|
+
global-exclude *.pyc
|
|
24
|
+
global-exclude __pycache__
|
|
25
|
+
global-exclude *.so
|
|
26
|
+
global-exclude .DS_Store
|
|
27
|
+
global-exclude *.a
|
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: apple-foundation-models
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: Python bindings for Apple's FoundationModels framework - on-device AI
|
|
5
|
+
Author: Ben Tucker
|
|
6
|
+
Maintainer: Ben Tucker
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/btucker/apple-foundation-models-py
|
|
9
|
+
Project-URL: Repository, https://github.com/btucker/apple-foundation-models-py
|
|
10
|
+
Project-URL: Documentation, https://github.com/btucker/apple-foundation-models-py#readme
|
|
11
|
+
Project-URL: Issues, https://github.com/btucker/apple-foundation-models-py/issues
|
|
12
|
+
Keywords: apple,intelligence,ai,llm,foundation-models,on-device
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Cython
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
25
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
26
|
+
Requires-Python: >=3.8
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Requires-Dist: typing-extensions>=4.0.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-asyncio>=0.20; extra == "dev"
|
|
33
|
+
Requires-Dist: black>=22.0; extra == "dev"
|
|
34
|
+
Requires-Dist: mypy>=0.991; extra == "dev"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# apple-foundation-models-py
|
|
38
|
+
|
|
39
|
+
Python bindings for Apple's FoundationModels framework - Direct access to on-device Apple Intelligence.
|
|
40
|
+
|
|
41
|
+
## Features
|
|
42
|
+
|
|
43
|
+
- **High-level Pythonic API**: Context managers, async/await, type hints
|
|
44
|
+
- **Async Streaming**: Native `async for` support for streaming responses
|
|
45
|
+
- **Type Safety**: Full type annotations with mypy support
|
|
46
|
+
- **Memory Safe**: Automatic resource cleanup, no manual memory management
|
|
47
|
+
- **Thread Safe**: All operations are thread-safe
|
|
48
|
+
|
|
49
|
+
## Requirements
|
|
50
|
+
|
|
51
|
+
- macOS 26.0+ (macOS Sequoia or later)
|
|
52
|
+
- Python 3.8 or higher
|
|
53
|
+
- Apple Intelligence enabled on your device
|
|
54
|
+
|
|
55
|
+
## Installation
|
|
56
|
+
|
|
57
|
+
### From PyPI
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install apple-foundation-models
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### From Source
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Clone the repository
|
|
67
|
+
git clone https://github.com/btucker/apple-foundation-models-py.git
|
|
68
|
+
cd apple-foundation-models-py
|
|
69
|
+
|
|
70
|
+
# Install (automatically builds Swift dylib and Cython extension)
|
|
71
|
+
pip install -e .
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Requirements:**
|
|
75
|
+
|
|
76
|
+
- macOS 26.0+ (Sequoia) with Apple Intelligence enabled
|
|
77
|
+
- Xcode command line tools (`xcode-select --install`)
|
|
78
|
+
- Python 3.8 or higher
|
|
79
|
+
|
|
80
|
+
**Note:** The Swift dylib is built automatically during installation.
|
|
81
|
+
|
|
82
|
+
## Quick Start
|
|
83
|
+
|
|
84
|
+
### Basic Usage
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from applefoundationmodels import Client
|
|
88
|
+
|
|
89
|
+
# Create a client (library auto-initializes)
|
|
90
|
+
with Client() as client:
|
|
91
|
+
# Check if Apple Intelligence is available
|
|
92
|
+
if not client.is_ready():
|
|
93
|
+
print("Apple Intelligence is not available")
|
|
94
|
+
print(client.get_availability_reason())
|
|
95
|
+
return
|
|
96
|
+
|
|
97
|
+
# Create a session
|
|
98
|
+
session = client.create_session(
|
|
99
|
+
instructions="You are a helpful assistant.",
|
|
100
|
+
enable_guardrails=True
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
# Generate a response
|
|
104
|
+
response = session.generate("What is the capital of France?")
|
|
105
|
+
print(response)
|
|
106
|
+
|
|
107
|
+
# Get conversation history
|
|
108
|
+
history = session.get_history()
|
|
109
|
+
for msg in history:
|
|
110
|
+
print(f"{msg['role']}: {msg['content']}")
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Async Streaming
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
import asyncio
|
|
117
|
+
from applefoundationmodels import Client
|
|
118
|
+
|
|
119
|
+
async def main():
|
|
120
|
+
with Client() as client:
|
|
121
|
+
session = client.create_session()
|
|
122
|
+
|
|
123
|
+
# Stream response chunks as they arrive
|
|
124
|
+
async for chunk in session.generate_stream("Tell me a story about a robot"):
|
|
125
|
+
print(chunk, end='', flush=True)
|
|
126
|
+
print() # Newline after stream
|
|
127
|
+
|
|
128
|
+
asyncio.run(main())
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Structured Output
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from applefoundationmodels import Client
|
|
135
|
+
|
|
136
|
+
with Client() as client:
|
|
137
|
+
session = client.create_session()
|
|
138
|
+
|
|
139
|
+
# Define a JSON schema
|
|
140
|
+
schema = {
|
|
141
|
+
"type": "object",
|
|
142
|
+
"properties": {
|
|
143
|
+
"name": {"type": "string"},
|
|
144
|
+
"age": {"type": "integer"},
|
|
145
|
+
"city": {"type": "string"}
|
|
146
|
+
},
|
|
147
|
+
"required": ["name", "age", "city"]
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
# Generate structured response
|
|
151
|
+
result = session.generate_structured(
|
|
152
|
+
"Extract person info: Alice is 28 and lives in Paris",
|
|
153
|
+
schema=schema
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
print(result['object']) # {'name': 'Alice', 'age': 28, 'city': 'Paris'}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Generation Parameters
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
# Control generation with parameters
|
|
163
|
+
response = session.generate(
|
|
164
|
+
"Write a creative story",
|
|
165
|
+
temperature=1.5, # Higher = more creative (0.0-2.0)
|
|
166
|
+
max_tokens=500, # Limit response length
|
|
167
|
+
seed=42 # Reproducible outputs
|
|
168
|
+
)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Session Management
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
with Client() as client:
|
|
175
|
+
# Create multiple sessions
|
|
176
|
+
chat_session = client.create_session(
|
|
177
|
+
instructions="You are a friendly chatbot"
|
|
178
|
+
)
|
|
179
|
+
code_session = client.create_session(
|
|
180
|
+
instructions="You are a code review assistant"
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
# Each session maintains separate conversation history
|
|
184
|
+
chat_response = chat_session.generate("Hello!")
|
|
185
|
+
code_response = code_session.generate("Review this code: ...")
|
|
186
|
+
|
|
187
|
+
# Clear history while keeping session
|
|
188
|
+
chat_session.clear_history()
|
|
189
|
+
|
|
190
|
+
# Manually add messages
|
|
191
|
+
chat_session.add_message("system", "Be concise")
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Statistics
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
with Client() as client:
|
|
198
|
+
session = client.create_session()
|
|
199
|
+
|
|
200
|
+
# Generate some responses
|
|
201
|
+
for i in range(5):
|
|
202
|
+
session.generate(f"Question {i}")
|
|
203
|
+
|
|
204
|
+
# Get statistics
|
|
205
|
+
stats = client.get_stats()
|
|
206
|
+
print(f"Total requests: {stats['total_requests']}")
|
|
207
|
+
print(f"Success rate: {stats['successful_requests'] / stats['total_requests'] * 100:.1f}%")
|
|
208
|
+
print(f"Avg response time: {stats['average_response_time']:.2f}s")
|
|
209
|
+
|
|
210
|
+
# Reset statistics
|
|
211
|
+
client.reset_stats()
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## API Reference
|
|
215
|
+
|
|
216
|
+
### Client
|
|
217
|
+
|
|
218
|
+
The main entry point for using libai.
|
|
219
|
+
|
|
220
|
+
```python
|
|
221
|
+
class Client:
|
|
222
|
+
def __init__() -> None: ...
|
|
223
|
+
def __enter__() -> Client: ...
|
|
224
|
+
def __exit__(...) -> None: ...
|
|
225
|
+
|
|
226
|
+
@staticmethod
|
|
227
|
+
def check_availability() -> Availability: ...
|
|
228
|
+
@staticmethod
|
|
229
|
+
def get_availability_reason() -> str: ...
|
|
230
|
+
@staticmethod
|
|
231
|
+
def is_ready() -> bool: ...
|
|
232
|
+
@staticmethod
|
|
233
|
+
def get_version() -> str: ...
|
|
234
|
+
@staticmethod
|
|
235
|
+
def get_supported_languages() -> List[str]: ...
|
|
236
|
+
|
|
237
|
+
def create_session(...) -> Session: ...
|
|
238
|
+
def get_stats() -> Stats: ...
|
|
239
|
+
def reset_stats() -> None: ...
|
|
240
|
+
def close() -> None: ...
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Session
|
|
244
|
+
|
|
245
|
+
Manages conversation state and text generation.
|
|
246
|
+
|
|
247
|
+
```python
|
|
248
|
+
class Session:
|
|
249
|
+
def __enter__() -> Session: ...
|
|
250
|
+
def __exit__(...) -> None: ...
|
|
251
|
+
|
|
252
|
+
def generate(prompt: str, **params) -> str: ...
|
|
253
|
+
def generate_structured(prompt: str, schema: dict, **params) -> dict: ...
|
|
254
|
+
async def generate_stream(prompt: str, **params) -> AsyncIterator[str]: ...
|
|
255
|
+
|
|
256
|
+
def get_history() -> List[dict]: ...
|
|
257
|
+
def clear_history() -> None: ...
|
|
258
|
+
def add_message(role: str, content: str) -> None: ...
|
|
259
|
+
def close() -> None: ...
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Types
|
|
263
|
+
|
|
264
|
+
```python
|
|
265
|
+
class Availability(IntEnum):
|
|
266
|
+
AVAILABLE = 1
|
|
267
|
+
DEVICE_NOT_ELIGIBLE = -1
|
|
268
|
+
NOT_ENABLED = -2
|
|
269
|
+
MODEL_NOT_READY = -3
|
|
270
|
+
|
|
271
|
+
class SessionConfig(TypedDict):
|
|
272
|
+
instructions: Optional[str]
|
|
273
|
+
tools_json: Optional[str]
|
|
274
|
+
enable_guardrails: bool
|
|
275
|
+
prewarm: bool
|
|
276
|
+
|
|
277
|
+
class GenerationParams(TypedDict):
|
|
278
|
+
temperature: float
|
|
279
|
+
max_tokens: int
|
|
280
|
+
seed: int
|
|
281
|
+
|
|
282
|
+
class Stats(TypedDict):
|
|
283
|
+
total_requests: int
|
|
284
|
+
successful_requests: int
|
|
285
|
+
failed_requests: int
|
|
286
|
+
total_tokens_generated: int
|
|
287
|
+
average_response_time: float
|
|
288
|
+
total_processing_time: float
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Exceptions
|
|
292
|
+
|
|
293
|
+
All exceptions inherit from `FoundationModelsError`:
|
|
294
|
+
|
|
295
|
+
- `InitializationError` - Library initialization failed
|
|
296
|
+
- `NotAvailableError` - Apple Intelligence not available
|
|
297
|
+
- `InvalidParametersError` - Invalid parameters
|
|
298
|
+
- `MemoryError` - Memory allocation failed
|
|
299
|
+
- `JSONParseError` - JSON parsing error
|
|
300
|
+
- `GenerationError` - Text generation failed
|
|
301
|
+
- `TimeoutError` - Operation timeout
|
|
302
|
+
- `SessionNotFoundError` - Session not found
|
|
303
|
+
- `StreamNotFoundError` - Stream not found
|
|
304
|
+
- `GuardrailViolationError` - Content blocked by safety filters
|
|
305
|
+
- `ToolNotFoundError` - Tool not registered
|
|
306
|
+
- `ToolExecutionError` - Tool execution failed
|
|
307
|
+
- `UnknownError` - Unknown error
|
|
308
|
+
|
|
309
|
+
## Examples
|
|
310
|
+
|
|
311
|
+
See the `examples/` directory for complete working examples:
|
|
312
|
+
|
|
313
|
+
- `basic_chat.py` - Simple conversation
|
|
314
|
+
- `streaming_chat.py` - Async streaming
|
|
315
|
+
- `tool_calling.py` - Tool registration (coming soon)
|
|
316
|
+
- `structured_output.py` - JSON schema validation
|
|
317
|
+
|
|
318
|
+
## Development
|
|
319
|
+
|
|
320
|
+
### Building from Source
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
# Install development dependencies
|
|
324
|
+
pip install -e ".[dev]"
|
|
325
|
+
|
|
326
|
+
# Run tests
|
|
327
|
+
pytest
|
|
328
|
+
|
|
329
|
+
# Type checking
|
|
330
|
+
mypy applefoundationmodels
|
|
331
|
+
|
|
332
|
+
# Format code
|
|
333
|
+
black applefoundationmodels examples
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Project Structure
|
|
337
|
+
|
|
338
|
+
```
|
|
339
|
+
apple-foundation-models-py/
|
|
340
|
+
├── applefoundationmodels/ # Python package
|
|
341
|
+
│ ├── __init__.py # Public API
|
|
342
|
+
│ ├── _foundationmodels.pyx # Cython bindings
|
|
343
|
+
│ ├── _foundationmodels.pxd # C declarations
|
|
344
|
+
│ ├── client.py # High-level Client
|
|
345
|
+
│ ├── session.py # Session management
|
|
346
|
+
│ ├── types.py # Type definitions
|
|
347
|
+
│ ├── exceptions.py # Exception classes
|
|
348
|
+
│ └── swift/ # Swift FoundationModels bindings
|
|
349
|
+
│ ├── foundation_models.swift # Swift implementation
|
|
350
|
+
│ └── foundation_models.h # C FFI header
|
|
351
|
+
├── lib/ # Swift dylib and modules (auto-generated)
|
|
352
|
+
│ └── libfoundation_models.dylib # Compiled Swift library
|
|
353
|
+
├── examples/ # Example scripts
|
|
354
|
+
└── tests/ # Unit tests
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## Architecture
|
|
358
|
+
|
|
359
|
+
apple-foundation-models-py uses a layered architecture for optimal performance:
|
|
360
|
+
|
|
361
|
+
```
|
|
362
|
+
Python API (client.py, session.py)
|
|
363
|
+
↓
|
|
364
|
+
Cython FFI (_foundationmodels.pyx)
|
|
365
|
+
↓
|
|
366
|
+
C FFI Layer (foundation_models.h)
|
|
367
|
+
↓
|
|
368
|
+
Swift Implementation (foundation_models.swift)
|
|
369
|
+
↓
|
|
370
|
+
FoundationModels Framework (Apple Intelligence)
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
**Key Design Decisions:**
|
|
374
|
+
|
|
375
|
+
- **Direct FoundationModels Integration**: No intermediate C library - Swift calls FoundationModels directly
|
|
376
|
+
- **Minimal Overhead**: C FFI layer provides thin wrapper for Python/Swift communication
|
|
377
|
+
- **Async Coordination**: Uses semaphores to bridge Swift's async/await with synchronous C calls
|
|
378
|
+
- **Streaming**: Real-time delta calculation from FoundationModels snapshot-based streaming
|
|
379
|
+
|
|
380
|
+
## Performance
|
|
381
|
+
|
|
382
|
+
- Cython-compiled for near-C performance
|
|
383
|
+
- Direct Swift → FoundationModels calls (no intermediate libraries)
|
|
384
|
+
- Async streaming with delta-based chunk delivery
|
|
385
|
+
- No GIL during Swift library calls (when possible)
|
|
386
|
+
|
|
387
|
+
## Troubleshooting
|
|
388
|
+
|
|
389
|
+
### Apple Intelligence not available
|
|
390
|
+
|
|
391
|
+
If you get `NotAvailableError`:
|
|
392
|
+
|
|
393
|
+
1. Ensure you're running macOS 26.0 (Sequoia) or later
|
|
394
|
+
2. Check System Settings → Apple Intelligence → Enable
|
|
395
|
+
3. Wait for models to download (check with `client.get_availability_reason()`)
|
|
396
|
+
|
|
397
|
+
### Import errors
|
|
398
|
+
|
|
399
|
+
If you get import errors after installation:
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
# Rebuild everything (Swift dylib + Cython extension)
|
|
403
|
+
pip install --force-reinstall --no-cache-dir -e .
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Compilation errors
|
|
407
|
+
|
|
408
|
+
Ensure you have Xcode command line tools:
|
|
409
|
+
|
|
410
|
+
```bash
|
|
411
|
+
xcode-select --install
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
If the Swift build fails during installation:
|
|
415
|
+
|
|
416
|
+
1. Verify macOS version: `sw_vers -productVersion` (should be 26.0+)
|
|
417
|
+
2. Check Swift compiler: `swiftc --version`
|
|
418
|
+
3. Clean and reinstall: `pip install --force-reinstall --no-cache-dir -e .`
|
|
419
|
+
|
|
420
|
+
## License
|
|
421
|
+
|
|
422
|
+
MIT License - see LICENSE file for details
|
|
423
|
+
|
|
424
|
+
## Contributing
|
|
425
|
+
|
|
426
|
+
Contributions are welcome! Please:
|
|
427
|
+
|
|
428
|
+
1. Fork the repository
|
|
429
|
+
2. Create a feature branch
|
|
430
|
+
3. Add tests for new functionality
|
|
431
|
+
4. Ensure all tests pass
|
|
432
|
+
5. Submit a pull request
|
|
433
|
+
|
|
434
|
+
## Links
|
|
435
|
+
|
|
436
|
+
- [FoundationModels Framework](https://developer.apple.com/documentation/FoundationModels)
|
|
437
|
+
- [Apple Intelligence Documentation](https://developer.apple.com/apple-intelligence/)
|
|
438
|
+
- [Issue Tracker](https://github.com/btucker/apple-foundation-models-py/issues)
|
|
439
|
+
|
|
440
|
+
## Acknowledgments
|
|
441
|
+
|
|
442
|
+
This project was inspired by and learned from several excellent works:
|
|
443
|
+
|
|
444
|
+
- **[libai](https://github.com/6over3/libai)** by 6over3 Institute - The original C library wrapper for FoundationModels that demonstrated the possibility of non-Objective-C access to Apple Intelligence. While we ultimately chose a direct Swift integration approach, the libai project's API design and documentation heavily influenced our Python API structure.
|
|
445
|
+
|
|
446
|
+
- **[apple-on-device-ai](https://github.com/Meridius-Labs/apple-on-device-ai)** by Meridius Labs - The Node.js bindings that showed the path to direct FoundationModels integration via Swift. Their architecture of using Swift → C FFI → JavaScript inspired our Swift → C FFI → Cython → Python approach, and their code examples were invaluable for understanding the FoundationModels API.
|