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.

Files changed (28) hide show
  1. apple_foundation_models-0.1.3/LICENSE +21 -0
  2. apple_foundation_models-0.1.3/MANIFEST.in +27 -0
  3. apple_foundation_models-0.1.3/PKG-INFO +446 -0
  4. apple_foundation_models-0.1.3/README.md +410 -0
  5. apple_foundation_models-0.1.3/apple_foundation_models.egg-info/PKG-INFO +446 -0
  6. apple_foundation_models-0.1.3/apple_foundation_models.egg-info/SOURCES.txt +26 -0
  7. apple_foundation_models-0.1.3/apple_foundation_models.egg-info/dependency_links.txt +1 -0
  8. apple_foundation_models-0.1.3/apple_foundation_models.egg-info/requires.txt +7 -0
  9. apple_foundation_models-0.1.3/apple_foundation_models.egg-info/top_level.txt +1 -0
  10. apple_foundation_models-0.1.3/applefoundationmodels/__init__.py +108 -0
  11. apple_foundation_models-0.1.3/applefoundationmodels/_foundationmodels.c +13192 -0
  12. apple_foundation_models-0.1.3/applefoundationmodels/_foundationmodels.pxd +70 -0
  13. apple_foundation_models-0.1.3/applefoundationmodels/_foundationmodels.pyx +407 -0
  14. apple_foundation_models-0.1.3/applefoundationmodels/base.py +36 -0
  15. apple_foundation_models-0.1.3/applefoundationmodels/client.py +203 -0
  16. apple_foundation_models-0.1.3/applefoundationmodels/constants.py +30 -0
  17. apple_foundation_models-0.1.3/applefoundationmodels/exceptions.py +115 -0
  18. apple_foundation_models-0.1.3/applefoundationmodels/py.typed +2 -0
  19. apple_foundation_models-0.1.3/applefoundationmodels/session.py +235 -0
  20. apple_foundation_models-0.1.3/applefoundationmodels/swift/foundation_models.h +58 -0
  21. apple_foundation_models-0.1.3/applefoundationmodels/swift/foundation_models.swift +371 -0
  22. apple_foundation_models-0.1.3/applefoundationmodels/types.py +124 -0
  23. apple_foundation_models-0.1.3/pyproject.toml +64 -0
  24. apple_foundation_models-0.1.3/setup.cfg +4 -0
  25. apple_foundation_models-0.1.3/setup.py +154 -0
  26. apple_foundation_models-0.1.3/tests/test_client.py +146 -0
  27. apple_foundation_models-0.1.3/tests/test_integration.py +384 -0
  28. 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.