apple-foundation-models 0.1.9__cp311-cp311-macosx_11_0_arm64.whl

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.

@@ -0,0 +1,108 @@
1
+ """
2
+ applefoundationmodels: Python bindings for Apple's FoundationModels framework
3
+
4
+ High-level Pythonic interface for accessing Apple Intelligence on-device
5
+ Foundation models.
6
+
7
+ Basic usage:
8
+ from applefoundationmodels import Client
9
+
10
+ with Client() as client:
11
+ # Check availability
12
+ if not client.is_ready():
13
+ print("Apple Intelligence not available")
14
+ return
15
+
16
+ # Create a session and generate response
17
+ session = client.create_session()
18
+ response = session.generate("Hello, how are you?")
19
+ print(response)
20
+
21
+ Async streaming:
22
+ import asyncio
23
+ from applefoundationmodels import Client
24
+
25
+ async def main():
26
+ with Client() as client:
27
+ session = client.create_session()
28
+ async for chunk in session.generate_stream("Tell me a story"):
29
+ print(chunk, end='', flush=True)
30
+
31
+ asyncio.run(main())
32
+ """
33
+
34
+ __version__ = "0.1.0"
35
+
36
+ # Public API exports
37
+ from .client import Client, client
38
+ from .session import Session
39
+ from .constants import (
40
+ DEFAULT_TEMPERATURE,
41
+ DEFAULT_MAX_TOKENS,
42
+ MIN_TEMPERATURE,
43
+ MAX_TEMPERATURE,
44
+ TemperaturePreset,
45
+ )
46
+ from .types import (
47
+ Result,
48
+ Availability,
49
+ SessionConfig,
50
+ GenerationParams,
51
+ Stats,
52
+ StreamCallback,
53
+ ToolCallback,
54
+ )
55
+ from .exceptions import (
56
+ FoundationModelsError,
57
+ InitializationError,
58
+ NotAvailableError,
59
+ InvalidParametersError,
60
+ MemoryError,
61
+ JSONParseError,
62
+ GenerationError,
63
+ TimeoutError,
64
+ SessionNotFoundError,
65
+ StreamNotFoundError,
66
+ GuardrailViolationError,
67
+ ToolNotFoundError,
68
+ ToolExecutionError,
69
+ UnknownError,
70
+ )
71
+
72
+ __all__ = [
73
+ # Version
74
+ "__version__",
75
+ # Main classes
76
+ "Client",
77
+ "Session",
78
+ "client",
79
+ # Constants
80
+ "DEFAULT_TEMPERATURE",
81
+ "DEFAULT_MAX_TOKENS",
82
+ "MIN_TEMPERATURE",
83
+ "MAX_TEMPERATURE",
84
+ "TemperaturePreset",
85
+ # Type definitions
86
+ "Result",
87
+ "Availability",
88
+ "SessionConfig",
89
+ "GenerationParams",
90
+ "Stats",
91
+ "StreamCallback",
92
+ "ToolCallback",
93
+ # Exceptions
94
+ "FoundationModelsError",
95
+ "InitializationError",
96
+ "NotAvailableError",
97
+ "InvalidParametersError",
98
+ "MemoryError",
99
+ "JSONParseError",
100
+ "GenerationError",
101
+ "TimeoutError",
102
+ "SessionNotFoundError",
103
+ "StreamNotFoundError",
104
+ "GuardrailViolationError",
105
+ "ToolNotFoundError",
106
+ "ToolExecutionError",
107
+ "UnknownError",
108
+ ]
@@ -0,0 +1,52 @@
1
+ """Type stubs for _foundationmodels Cython extension."""
2
+
3
+ from typing import Any, Callable, Dict, List, Optional
4
+
5
+ # Initialization and cleanup
6
+ def init() -> None: ...
7
+ def cleanup() -> None: ...
8
+ def get_version() -> str: ...
9
+
10
+ # Availability functions
11
+ def check_availability() -> int: ...
12
+ def get_availability_reason() -> Optional[str]: ...
13
+ def is_ready() -> bool: ...
14
+
15
+ # Language support
16
+ def get_supported_languages_count() -> int: ...
17
+ def get_supported_language(index: int) -> Optional[str]: ...
18
+
19
+ # Session management
20
+ def create_session(config: Optional[Dict[str, Any]] = None) -> int: ...
21
+
22
+ # Text generation
23
+ def generate(prompt: str, temperature: float = 1.0, max_tokens: int = 1024) -> str: ...
24
+
25
+ # Structured generation
26
+ def generate_structured(
27
+ prompt: str,
28
+ schema: Dict[str, Any],
29
+ temperature: float = 1.0,
30
+ max_tokens: int = 1024,
31
+ ) -> Dict[str, Any]: ...
32
+
33
+ # Streaming generation
34
+ def generate_stream(
35
+ prompt: str,
36
+ callback: Callable[[Optional[str]], None],
37
+ temperature: float = 1.0,
38
+ max_tokens: int = 1024,
39
+ ) -> None: ...
40
+
41
+ # History management
42
+ def get_history() -> List[Any]: ...
43
+ def clear_history() -> None: ...
44
+ def add_message(role: str, content: str) -> None: ...
45
+
46
+ # Tool calling
47
+ def register_tools(tools: Dict[str, Callable]) -> None: ...
48
+ def get_transcript() -> List[Dict[str, Any]]: ...
49
+
50
+ # Statistics
51
+ def get_stats() -> Dict[str, Any]: ...
52
+ def reset_stats() -> None: ...
@@ -0,0 +1,36 @@
1
+ """
2
+ Base classes for applefoundationmodels.
3
+
4
+ Provides base functionality for context-managed resources.
5
+ """
6
+
7
+ from abc import ABC, abstractmethod
8
+ from typing import TypeVar
9
+
10
+ T = TypeVar("T", bound="ContextManagedResource")
11
+
12
+
13
+ class ContextManagedResource(ABC):
14
+ """
15
+ Base class for resources that support context manager protocol.
16
+
17
+ Provides standard __enter__ and __exit__ methods that call the
18
+ close() method on exit. Subclasses must implement close().
19
+ """
20
+
21
+ def __enter__(self: T) -> T:
22
+ """Context manager entry."""
23
+ return self
24
+
25
+ def __exit__(self, exc_type, exc_val, exc_tb) -> None:
26
+ """Context manager exit with automatic cleanup."""
27
+ self.close()
28
+
29
+ @abstractmethod
30
+ def close(self) -> None:
31
+ """
32
+ Close and cleanup resources.
33
+
34
+ Must be implemented by subclasses.
35
+ """
36
+ pass
@@ -0,0 +1,231 @@
1
+ """
2
+ High-level Client API for applefoundationmodels Python bindings.
3
+
4
+ Provides a Pythonic interface to Apple's FoundationModels framework with
5
+ context managers, automatic resource cleanup, and integration with the Session class.
6
+ """
7
+
8
+ import platform
9
+ from typing import Optional, List, cast
10
+ from contextlib import contextmanager
11
+
12
+ from . import _foundationmodels
13
+ from .base import ContextManagedResource
14
+ from .types import Availability, Stats
15
+ from .session import Session
16
+ from .exceptions import NotAvailableError
17
+
18
+
19
+ class Client(ContextManagedResource):
20
+ """
21
+ High-level client for Apple Intelligence operations.
22
+
23
+ This class provides a Pythonic interface to Apple's FoundationModels framework,
24
+ managing sessions with automatic resource cleanup.
25
+
26
+ Usage:
27
+ with Client() as client:
28
+ session = client.create_session()
29
+ response = session.generate("Hello!")
30
+ print(response)
31
+ """
32
+
33
+ _initialized: bool = False
34
+
35
+ def __init__(self):
36
+ """
37
+ Create a new FoundationModels client.
38
+
39
+ The library is automatically initialized on first client creation.
40
+
41
+ Raises:
42
+ InitializationError: If library initialization fails
43
+ NotAvailableError: If Apple Intelligence is not available
44
+ RuntimeError: If platform is not supported
45
+ """
46
+ # Check platform requirements
47
+ if platform.system() != "Darwin":
48
+ raise NotAvailableError(
49
+ "Apple Intelligence is only available on macOS. "
50
+ f"Current platform: {platform.system()}"
51
+ )
52
+
53
+ # Check macOS version
54
+ mac_ver = platform.mac_ver()[0]
55
+ if mac_ver:
56
+ try:
57
+ major_version = int(mac_ver.split(".")[0])
58
+ if major_version < 26:
59
+ raise NotAvailableError(
60
+ f"Apple Intelligence requires macOS 26.0 or later. "
61
+ f"Current version: {mac_ver}"
62
+ )
63
+ except (ValueError, IndexError):
64
+ # If we can't parse the version, let it try anyway
65
+ pass
66
+
67
+ # Initialize library on first client creation
68
+ if not Client._initialized:
69
+ _foundationmodels.init()
70
+ Client._initialized = True
71
+
72
+ self._sessions: List[Session] = []
73
+
74
+ def close(self) -> None:
75
+ """
76
+ Close the client and cleanup all resources.
77
+
78
+ Destroys all sessions.
79
+ """
80
+ # Close all sessions
81
+ for session in self._sessions:
82
+ session.close()
83
+ self._sessions.clear()
84
+
85
+ @staticmethod
86
+ def check_availability() -> Availability:
87
+ """
88
+ Check Apple Intelligence availability on this device.
89
+
90
+ This is a static method that can be called without creating a client.
91
+
92
+ Returns:
93
+ Availability status enum value
94
+
95
+ Example:
96
+ >>> from applefoundationmodels import Client, Availability
97
+ >>> status = Client.check_availability()
98
+ >>> if status == Availability.AVAILABLE:
99
+ ... print("Apple Intelligence is available!")
100
+ """
101
+ return Availability(_foundationmodels.check_availability())
102
+
103
+ @staticmethod
104
+ def get_availability_reason() -> Optional[str]:
105
+ """
106
+ Get detailed availability status message.
107
+
108
+ Returns:
109
+ Detailed status description with actionable guidance,
110
+ or None if library not initialized
111
+ """
112
+ return _foundationmodels.get_availability_reason()
113
+
114
+ @staticmethod
115
+ def is_ready() -> bool:
116
+ """
117
+ Check if Apple Intelligence is ready for immediate use.
118
+
119
+ Returns:
120
+ True if ready for use, False otherwise
121
+ """
122
+ return _foundationmodels.is_ready()
123
+
124
+ @staticmethod
125
+ def get_version() -> str:
126
+ """
127
+ Get library version string.
128
+
129
+ Returns:
130
+ Version string in format "major.minor.patch"
131
+ """
132
+ return _foundationmodels.get_version()
133
+
134
+ @staticmethod
135
+ def get_supported_languages() -> List[str]:
136
+ """
137
+ Get list of languages supported by Apple Intelligence.
138
+
139
+ Returns:
140
+ List of localized language display names
141
+ """
142
+ count = _foundationmodels.get_supported_languages_count()
143
+ return [
144
+ lang
145
+ for i in range(count)
146
+ if (lang := _foundationmodels.get_supported_language(i)) is not None
147
+ ]
148
+
149
+ def create_session(
150
+ self,
151
+ instructions: Optional[str] = None,
152
+ tools_json: Optional[str] = None,
153
+ enable_guardrails: bool = True,
154
+ prewarm: bool = False,
155
+ ) -> Session:
156
+ """
157
+ Create a new AI session.
158
+
159
+ Sessions maintain conversation state and can be configured with
160
+ tools and instructions.
161
+
162
+ Args:
163
+ instructions: Optional system instructions to guide AI behavior
164
+ tools_json: Optional JSON array of tool definitions in Claude format
165
+ enable_guardrails: Whether to enable content safety filtering
166
+ prewarm: Whether to preload session resources for faster first response
167
+
168
+ Returns:
169
+ New Session instance
170
+
171
+ Raises:
172
+ Various FoundationModelsError subclasses on failure
173
+
174
+ Example:
175
+ >>> session = client.create_session(
176
+ ... instructions="You are a helpful assistant.",
177
+ ... enable_guardrails=True
178
+ ... )
179
+ """
180
+ config = {}
181
+ if instructions is not None:
182
+ config["instructions"] = instructions
183
+ # Note: tools_json, enable_guardrails, prewarm not supported in simplified API
184
+
185
+ session_id = _foundationmodels.create_session(config if config else None)
186
+ session = Session(session_id, config if config else None)
187
+ self._sessions.append(session)
188
+ return session
189
+
190
+ def get_stats(self) -> Stats:
191
+ """
192
+ Get generation statistics for this client.
193
+
194
+ Returns:
195
+ Dictionary with statistics fields including request counts,
196
+ success rates, and performance metrics
197
+
198
+ Example:
199
+ >>> stats = client.get_stats()
200
+ >>> print(f"Total requests: {stats['total_requests']}")
201
+ >>> print(f"Average response time: {stats['average_response_time']:.2f}s")
202
+ """
203
+ return cast(Stats, _foundationmodels.get_stats())
204
+
205
+ def reset_stats(self) -> None:
206
+ """
207
+ Reset generation statistics for this client.
208
+
209
+ Clears all accumulated statistics, resetting counters to zero.
210
+ """
211
+ _foundationmodels.reset_stats()
212
+
213
+
214
+ @contextmanager
215
+ def client():
216
+ """
217
+ Context manager factory for creating a Client.
218
+
219
+ Usage:
220
+ with client() as c:
221
+ session = c.create_session()
222
+ response = session.generate("Hello!")
223
+
224
+ Yields:
225
+ Client instance with automatic cleanup
226
+ """
227
+ c = Client()
228
+ try:
229
+ yield c
230
+ finally:
231
+ c.close()
@@ -0,0 +1,30 @@
1
+ """
2
+ Constants for applefoundationmodels.
3
+
4
+ Provides default values and presets for generation parameters.
5
+ """
6
+
7
+ # Generation defaults
8
+ DEFAULT_TEMPERATURE = 1.0
9
+ DEFAULT_MAX_TOKENS = 1024
10
+
11
+ # Temperature bounds
12
+ MIN_TEMPERATURE = 0.0
13
+ MAX_TEMPERATURE = 2.0
14
+
15
+
16
+ class TemperaturePreset:
17
+ """
18
+ Common temperature presets for different use cases.
19
+
20
+ Temperature controls randomness in generation:
21
+ - Lower values (0.1-0.3): More deterministic, good for facts and precision
22
+ - Medium values (0.5-0.7): Balanced creativity and consistency
23
+ - Higher values (1.0-1.5): More creative and varied outputs
24
+ """
25
+
26
+ DETERMINISTIC = 0.1 # Very low randomness, highly consistent
27
+ FACTUAL = 0.3 # Low randomness, good for factual responses
28
+ BALANCED = 0.7 # Balanced creativity and consistency
29
+ CREATIVE = 1.0 # More creative responses
30
+ VERY_CREATIVE = 1.5 # High creativity and variety
@@ -0,0 +1,134 @@
1
+ """
2
+ Exception hierarchy for applefoundationmodels Python bindings.
3
+
4
+ All exceptions raised by the library inherit from FoundationModelsError.
5
+ Each exception corresponds to a specific error code from the Swift API.
6
+ """
7
+
8
+ from typing import Optional
9
+
10
+
11
+ class FoundationModelsError(Exception):
12
+ """Base exception for all FoundationModels errors."""
13
+
14
+ def __init__(self, message: str, error_code: Optional[int] = None):
15
+ super().__init__(message)
16
+ self.message = message
17
+ self.error_code = error_code
18
+
19
+
20
+ class InitializationError(FoundationModelsError):
21
+ """Library initialization failed."""
22
+
23
+ pass
24
+
25
+
26
+ class NotAvailableError(FoundationModelsError):
27
+ """Apple Intelligence not available on this device."""
28
+
29
+ pass
30
+
31
+
32
+ class InvalidParametersError(FoundationModelsError):
33
+ """Invalid parameters provided to function."""
34
+
35
+ pass
36
+
37
+
38
+ class MemoryError(FoundationModelsError):
39
+ """Memory allocation error."""
40
+
41
+ pass
42
+
43
+
44
+ class JSONParseError(FoundationModelsError):
45
+ """JSON parsing or validation error."""
46
+
47
+ pass
48
+
49
+
50
+ class GenerationError(FoundationModelsError):
51
+ """Text generation error."""
52
+
53
+ pass
54
+
55
+
56
+ class TimeoutError(FoundationModelsError):
57
+ """Operation timeout."""
58
+
59
+ pass
60
+
61
+
62
+ class SessionNotFoundError(FoundationModelsError):
63
+ """Session ID not found."""
64
+
65
+ pass
66
+
67
+
68
+ class StreamNotFoundError(FoundationModelsError):
69
+ """Stream ID not found or already completed."""
70
+
71
+ pass
72
+
73
+
74
+ class GuardrailViolationError(FoundationModelsError):
75
+ """Content blocked by safety filters."""
76
+
77
+ pass
78
+
79
+
80
+ class ToolNotFoundError(FoundationModelsError):
81
+ """Tool callback not registered for session."""
82
+
83
+ pass
84
+
85
+
86
+ class ToolExecutionError(FoundationModelsError):
87
+ """Tool execution failed or returned invalid result."""
88
+
89
+ pass
90
+
91
+
92
+ class ToolCallError(FoundationModelsError):
93
+ """Tool call error (validation, schema, etc.)."""
94
+
95
+ pass
96
+
97
+
98
+ class UnknownError(FoundationModelsError):
99
+ """Unknown error occurred."""
100
+
101
+ pass
102
+
103
+
104
+ # Mapping from ai_result_t error codes to exception classes
105
+ ERROR_CODE_TO_EXCEPTION = {
106
+ -1: InitializationError,
107
+ -2: NotAvailableError,
108
+ -3: InvalidParametersError,
109
+ -4: MemoryError,
110
+ -5: JSONParseError,
111
+ -6: GenerationError,
112
+ -7: TimeoutError,
113
+ -8: SessionNotFoundError,
114
+ -9: StreamNotFoundError,
115
+ -10: GuardrailViolationError,
116
+ -11: ToolNotFoundError,
117
+ -12: ToolExecutionError,
118
+ -99: UnknownError,
119
+ }
120
+
121
+
122
+ def raise_for_error_code(error_code: int, message: str) -> None:
123
+ """
124
+ Raise the appropriate exception for a given error code.
125
+
126
+ Args:
127
+ error_code: The error code from the Swift API
128
+ message: Error message to include in the exception
129
+
130
+ Raises:
131
+ FoundationModelsError: The appropriate exception subclass for the error code
132
+ """
133
+ exception_class = ERROR_CODE_TO_EXCEPTION.get(error_code, UnknownError)
134
+ raise exception_class(message, error_code)
@@ -0,0 +1,2 @@
1
+ # Marker file for PEP 561
2
+ # This package supports type checking