apple-foundation-models 0.1.3__tar.gz → 0.1.9__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.9/MANIFEST.in +17 -0
- {apple_foundation_models-0.1.3/apple_foundation_models.egg-info → apple_foundation_models-0.1.9}/PKG-INFO +175 -14
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/README.md +166 -8
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9/apple_foundation_models.egg-info}/PKG-INFO +175 -14
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/apple_foundation_models.egg-info/SOURCES.txt +5 -1
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/apple_foundation_models.egg-info/requires.txt +4 -0
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/applefoundationmodels/_foundationmodels.c +8309 -4249
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/applefoundationmodels/_foundationmodels.pxd +19 -0
- apple_foundation_models-0.1.9/applefoundationmodels/_foundationmodels.pyi +52 -0
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/applefoundationmodels/_foundationmodels.pyx +218 -0
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/applefoundationmodels/base.py +1 -1
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/applefoundationmodels/client.py +35 -7
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/applefoundationmodels/constants.py +3 -3
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/applefoundationmodels/exceptions.py +19 -0
- apple_foundation_models-0.1.9/applefoundationmodels/pydantic_compat.py +144 -0
- apple_foundation_models-0.1.9/applefoundationmodels/session.py +448 -0
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/applefoundationmodels/swift/foundation_models.h +17 -0
- apple_foundation_models-0.1.9/applefoundationmodels/swift/foundation_models.swift +1024 -0
- apple_foundation_models-0.1.9/applefoundationmodels/tools.py +304 -0
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/applefoundationmodels/types.py +47 -0
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/pyproject.toml +35 -10
- apple_foundation_models-0.1.9/setup.py +173 -0
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/tests/test_client.py +4 -1
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/tests/test_integration.py +46 -50
- apple_foundation_models-0.1.9/tests/test_session.py +475 -0
- apple_foundation_models-0.1.9/tests/test_tools.py +423 -0
- apple_foundation_models-0.1.3/MANIFEST.in +0 -27
- apple_foundation_models-0.1.3/applefoundationmodels/session.py +0 -235
- apple_foundation_models-0.1.3/applefoundationmodels/swift/foundation_models.swift +0 -371
- apple_foundation_models-0.1.3/setup.py +0 -154
- apple_foundation_models-0.1.3/tests/test_session.py +0 -163
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/LICENSE +0 -0
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/apple_foundation_models.egg-info/dependency_links.txt +0 -0
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/apple_foundation_models.egg-info/top_level.txt +0 -0
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/applefoundationmodels/__init__.py +0 -0
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/applefoundationmodels/py.typed +0 -0
- {apple_foundation_models-0.1.3 → apple_foundation_models-0.1.9}/setup.cfg +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Controls what goes into the source distribution (.tar.gz)
|
|
2
|
+
# The source distribution must contain all files needed to build the wheel
|
|
3
|
+
|
|
4
|
+
# Documentation
|
|
5
|
+
include README.md
|
|
6
|
+
include LICENSE
|
|
7
|
+
|
|
8
|
+
# Cython source files needed for compilation
|
|
9
|
+
include applefoundationmodels/*.pyx
|
|
10
|
+
include applefoundationmodels/*.pxd
|
|
11
|
+
|
|
12
|
+
# Swift source needed for compilation
|
|
13
|
+
include applefoundationmodels/swift/*.swift
|
|
14
|
+
include applefoundationmodels/swift/*.h
|
|
15
|
+
|
|
16
|
+
# Exclude the lib build directory if it exists
|
|
17
|
+
prune lib
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apple-foundation-models
|
|
3
|
-
Version: 0.1.
|
|
4
|
-
Summary: Python bindings for Apple's FoundationModels framework - on-device AI
|
|
3
|
+
Version: 0.1.9
|
|
4
|
+
Summary: Python bindings for Apple's FoundationModels framework - on-device AI (requires macOS 26.0+)
|
|
5
5
|
Author: Ben Tucker
|
|
6
6
|
Maintainer: Ben Tucker
|
|
7
|
-
License: MIT
|
|
7
|
+
License-Expression: MIT
|
|
8
8
|
Project-URL: Homepage, https://github.com/btucker/apple-foundation-models-py
|
|
9
9
|
Project-URL: Repository, https://github.com/btucker/apple-foundation-models-py
|
|
10
10
|
Project-URL: Documentation, https://github.com/btucker/apple-foundation-models-py#readme
|
|
@@ -12,35 +12,39 @@ Project-URL: Issues, https://github.com/btucker/apple-foundation-models-py/issue
|
|
|
12
12
|
Keywords: apple,intelligence,ai,llm,foundation-models,on-device
|
|
13
13
|
Classifier: Development Status :: 3 - Alpha
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
15
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
16
15
|
Classifier: Operating System :: MacOS :: MacOS X
|
|
17
16
|
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
19
17
|
Classifier: Programming Language :: Python :: 3.9
|
|
20
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
21
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
22
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
23
|
Classifier: Programming Language :: Cython
|
|
24
24
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
25
25
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
26
|
-
Requires-Python: >=3.
|
|
26
|
+
Requires-Python: >=3.9
|
|
27
27
|
Description-Content-Type: text/markdown
|
|
28
28
|
License-File: LICENSE
|
|
29
29
|
Requires-Dist: typing-extensions>=4.0.0
|
|
30
30
|
Provides-Extra: dev
|
|
31
31
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
32
32
|
Requires-Dist: pytest-asyncio>=0.20; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
33
34
|
Requires-Dist: black>=22.0; extra == "dev"
|
|
34
35
|
Requires-Dist: mypy>=0.991; extra == "dev"
|
|
36
|
+
Provides-Extra: pydantic
|
|
37
|
+
Requires-Dist: pydantic>=2.0; extra == "pydantic"
|
|
35
38
|
Dynamic: license-file
|
|
36
39
|
|
|
37
|
-
# apple-foundation-models
|
|
40
|
+
# apple-foundation-models
|
|
38
41
|
|
|
39
42
|
Python bindings for Apple's FoundationModels framework - Direct access to on-device Apple Intelligence.
|
|
40
43
|
|
|
41
44
|
## Features
|
|
42
45
|
|
|
43
46
|
- **High-level Pythonic API**: Context managers, async/await, type hints
|
|
47
|
+
- **Structured Outputs**: JSON Schema and Pydantic model support
|
|
44
48
|
- **Async Streaming**: Native `async for` support for streaming responses
|
|
45
49
|
- **Type Safety**: Full type annotations with mypy support
|
|
46
50
|
- **Memory Safe**: Automatic resource cleanup, no manual memory management
|
|
@@ -49,7 +53,7 @@ Python bindings for Apple's FoundationModels framework - Direct access to on-dev
|
|
|
49
53
|
## Requirements
|
|
50
54
|
|
|
51
55
|
- macOS 26.0+ (macOS Sequoia or later)
|
|
52
|
-
- Python 3.
|
|
56
|
+
- Python 3.9 or higher
|
|
53
57
|
- Apple Intelligence enabled on your device
|
|
54
58
|
|
|
55
59
|
## Installation
|
|
@@ -60,6 +64,13 @@ Python bindings for Apple's FoundationModels framework - Direct access to on-dev
|
|
|
60
64
|
pip install apple-foundation-models
|
|
61
65
|
```
|
|
62
66
|
|
|
67
|
+
**Optional dependencies:**
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# For Pydantic model support in structured outputs
|
|
71
|
+
pip install apple-foundation-models[pydantic]
|
|
72
|
+
```
|
|
73
|
+
|
|
63
74
|
### From Source
|
|
64
75
|
|
|
65
76
|
```bash
|
|
@@ -75,7 +86,7 @@ pip install -e .
|
|
|
75
86
|
|
|
76
87
|
- macOS 26.0+ (Sequoia) with Apple Intelligence enabled
|
|
77
88
|
- Xcode command line tools (`xcode-select --install`)
|
|
78
|
-
- Python 3.
|
|
89
|
+
- Python 3.9 or higher
|
|
79
90
|
|
|
80
91
|
**Note:** The Swift dylib is built automatically during installation.
|
|
81
92
|
|
|
@@ -153,9 +164,137 @@ with Client() as client:
|
|
|
153
164
|
schema=schema
|
|
154
165
|
)
|
|
155
166
|
|
|
156
|
-
print(result
|
|
167
|
+
print(result) # {'name': 'Alice', 'age': 28, 'city': 'Paris'}
|
|
157
168
|
```
|
|
158
169
|
|
|
170
|
+
#### Using Pydantic Models
|
|
171
|
+
|
|
172
|
+
You can also use Pydantic models for structured outputs (requires `pip install pydantic>=2.0`):
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
from applefoundationmodels import Client
|
|
176
|
+
from pydantic import BaseModel
|
|
177
|
+
|
|
178
|
+
class Person(BaseModel):
|
|
179
|
+
name: str
|
|
180
|
+
age: int
|
|
181
|
+
city: str
|
|
182
|
+
|
|
183
|
+
with Client() as client:
|
|
184
|
+
session = client.create_session()
|
|
185
|
+
|
|
186
|
+
# Pass Pydantic model directly - no need for JSON schema!
|
|
187
|
+
result = session.generate_structured(
|
|
188
|
+
"Extract person info: Alice is 28 and lives in Paris",
|
|
189
|
+
schema=Person
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
print(result) # {'name': 'Alice', 'age': 28, 'city': 'Paris'}
|
|
193
|
+
|
|
194
|
+
# Parse directly into a Pydantic model for validation
|
|
195
|
+
person = Person(**result)
|
|
196
|
+
print(person.name, person.age, person.city) # Alice 28 Paris
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Tool Calling
|
|
200
|
+
|
|
201
|
+
Tool calling allows the model to call your Python functions to access real-time data, perform actions, or integrate with external systems. Tools work with a simple decorator-based API:
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
from applefoundationmodels import Client
|
|
205
|
+
|
|
206
|
+
with Client() as client:
|
|
207
|
+
session = client.create_session()
|
|
208
|
+
|
|
209
|
+
# Register a tool with the @session.tool decorator
|
|
210
|
+
@session.tool(description="Get current weather for a location")
|
|
211
|
+
def get_weather(location: str, units: str = "celsius") -> str:
|
|
212
|
+
"""Fetch weather information from your weather API."""
|
|
213
|
+
# Your implementation here
|
|
214
|
+
return f"Weather in {location}: 22°{units[0].upper()}, sunny"
|
|
215
|
+
|
|
216
|
+
@session.tool()
|
|
217
|
+
def calculate(expression: str) -> float:
|
|
218
|
+
"""Evaluate a mathematical expression safely."""
|
|
219
|
+
# Your implementation here
|
|
220
|
+
return eval(expression) # Use safe_eval in production!
|
|
221
|
+
|
|
222
|
+
# The model will automatically call tools when needed
|
|
223
|
+
response = session.generate(
|
|
224
|
+
"What's the weather in Paris and what's 15 times 23?"
|
|
225
|
+
)
|
|
226
|
+
print(response)
|
|
227
|
+
# "The weather in Paris is 22°C and sunny. 15 times 23 equals 345."
|
|
228
|
+
|
|
229
|
+
# View the full conversation including tool calls
|
|
230
|
+
for entry in session.transcript:
|
|
231
|
+
print(f"{entry['type']}: {entry.get('content', '')}")
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**Features:**
|
|
235
|
+
- **Automatic schema generation** from Python type hints
|
|
236
|
+
- **Parallel tool execution** when the model calls multiple tools
|
|
237
|
+
- **Full transcript access** showing all tool calls and outputs
|
|
238
|
+
- **Error handling** with detailed error information
|
|
239
|
+
- **Type-safe** with complete type annotations
|
|
240
|
+
|
|
241
|
+
**Schema Extraction:**
|
|
242
|
+
|
|
243
|
+
The library automatically extracts JSON schemas from your Python functions:
|
|
244
|
+
|
|
245
|
+
```python
|
|
246
|
+
@session.tool(description="Search documentation")
|
|
247
|
+
def search_docs(query: str, limit: int = 10, category: str = "all") -> list:
|
|
248
|
+
"""Search the documentation database."""
|
|
249
|
+
# Implementation...
|
|
250
|
+
return results
|
|
251
|
+
|
|
252
|
+
# Automatically generates:
|
|
253
|
+
# {
|
|
254
|
+
# "name": "search_docs",
|
|
255
|
+
# "description": "Search documentation",
|
|
256
|
+
# "parameters": {
|
|
257
|
+
# "type": "object",
|
|
258
|
+
# "properties": {
|
|
259
|
+
# "query": {"type": "string"},
|
|
260
|
+
# "limit": {"type": "integer"},
|
|
261
|
+
# "category": {"type": "string"}
|
|
262
|
+
# },
|
|
263
|
+
# "required": ["query"]
|
|
264
|
+
# }
|
|
265
|
+
# }
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**Transcript Access:**
|
|
269
|
+
|
|
270
|
+
View the complete conversation history including tool interactions:
|
|
271
|
+
|
|
272
|
+
```python
|
|
273
|
+
# After generating with tools
|
|
274
|
+
for entry in session.transcript:
|
|
275
|
+
match entry['type']:
|
|
276
|
+
case 'prompt':
|
|
277
|
+
print(f"User: {entry['content']}")
|
|
278
|
+
case 'tool_calls':
|
|
279
|
+
for call in entry['tool_calls']:
|
|
280
|
+
print(f"Calling tool: {call['id']}")
|
|
281
|
+
case 'tool_output':
|
|
282
|
+
print(f"Tool result: {entry['content']}")
|
|
283
|
+
case 'response':
|
|
284
|
+
print(f"Assistant: {entry['content']}")
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**Supported Parameter Types:**
|
|
288
|
+
|
|
289
|
+
Tool calling works with various parameter signatures:
|
|
290
|
+
- No parameters
|
|
291
|
+
- Single parameters (string, int, float, bool)
|
|
292
|
+
- Multiple parameters with mixed types
|
|
293
|
+
- Optional parameters with default values
|
|
294
|
+
- Lists and nested objects
|
|
295
|
+
|
|
296
|
+
See `examples/tool_calling_comprehensive.py` for complete examples of all supported patterns.
|
|
297
|
+
|
|
159
298
|
### Generation Parameters
|
|
160
299
|
|
|
161
300
|
```python
|
|
@@ -253,6 +392,10 @@ class Session:
|
|
|
253
392
|
def generate_structured(prompt: str, schema: dict, **params) -> dict: ...
|
|
254
393
|
async def generate_stream(prompt: str, **params) -> AsyncIterator[str]: ...
|
|
255
394
|
|
|
395
|
+
def tool(description: str = None, name: str = None) -> Callable: ...
|
|
396
|
+
@property
|
|
397
|
+
def transcript() -> List[dict]: ...
|
|
398
|
+
|
|
256
399
|
def get_history() -> List[dict]: ...
|
|
257
400
|
def clear_history() -> None: ...
|
|
258
401
|
def add_message(role: str, content: str) -> None: ...
|
|
@@ -304,6 +447,7 @@ All exceptions inherit from `FoundationModelsError`:
|
|
|
304
447
|
- `GuardrailViolationError` - Content blocked by safety filters
|
|
305
448
|
- `ToolNotFoundError` - Tool not registered
|
|
306
449
|
- `ToolExecutionError` - Tool execution failed
|
|
450
|
+
- `ToolCallError` - Tool call error (validation, schema, etc.)
|
|
307
451
|
- `UnknownError` - Unknown error
|
|
308
452
|
|
|
309
453
|
## Examples
|
|
@@ -312,24 +456,41 @@ See the `examples/` directory for complete working examples:
|
|
|
312
456
|
|
|
313
457
|
- `basic_chat.py` - Simple conversation
|
|
314
458
|
- `streaming_chat.py` - Async streaming
|
|
315
|
-
- `tool_calling.py` - Tool registration (coming soon)
|
|
316
459
|
- `structured_output.py` - JSON schema validation
|
|
460
|
+
- `tool_calling_comprehensive.py` - Complete tool calling demonstration with all parameter types
|
|
317
461
|
|
|
318
462
|
## Development
|
|
319
463
|
|
|
320
464
|
### Building from Source
|
|
321
465
|
|
|
466
|
+
This project uses [uv](https://docs.astral.sh/uv/) for fast, reliable builds and dependency management:
|
|
467
|
+
|
|
322
468
|
```bash
|
|
469
|
+
# Install uv (if not already installed)
|
|
470
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
471
|
+
|
|
323
472
|
# Install development dependencies
|
|
324
|
-
|
|
473
|
+
uv sync --extra dev
|
|
325
474
|
|
|
326
475
|
# Run tests
|
|
327
|
-
pytest
|
|
476
|
+
uv run pytest
|
|
328
477
|
|
|
329
478
|
# Type checking
|
|
330
|
-
mypy applefoundationmodels
|
|
479
|
+
uv run mypy applefoundationmodels
|
|
331
480
|
|
|
332
481
|
# Format code
|
|
482
|
+
uv run black applefoundationmodels examples
|
|
483
|
+
|
|
484
|
+
# Build wheels
|
|
485
|
+
uv build --wheel
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
You can also use pip if preferred:
|
|
489
|
+
|
|
490
|
+
```bash
|
|
491
|
+
pip install -e ".[dev]"
|
|
492
|
+
pytest
|
|
493
|
+
mypy applefoundationmodels
|
|
333
494
|
black applefoundationmodels examples
|
|
334
495
|
```
|
|
335
496
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
# apple-foundation-models
|
|
1
|
+
# apple-foundation-models
|
|
2
2
|
|
|
3
3
|
Python bindings for Apple's FoundationModels framework - Direct access to on-device Apple Intelligence.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- **High-level Pythonic API**: Context managers, async/await, type hints
|
|
8
|
+
- **Structured Outputs**: JSON Schema and Pydantic model support
|
|
8
9
|
- **Async Streaming**: Native `async for` support for streaming responses
|
|
9
10
|
- **Type Safety**: Full type annotations with mypy support
|
|
10
11
|
- **Memory Safe**: Automatic resource cleanup, no manual memory management
|
|
@@ -13,7 +14,7 @@ Python bindings for Apple's FoundationModels framework - Direct access to on-dev
|
|
|
13
14
|
## Requirements
|
|
14
15
|
|
|
15
16
|
- macOS 26.0+ (macOS Sequoia or later)
|
|
16
|
-
- Python 3.
|
|
17
|
+
- Python 3.9 or higher
|
|
17
18
|
- Apple Intelligence enabled on your device
|
|
18
19
|
|
|
19
20
|
## Installation
|
|
@@ -24,6 +25,13 @@ Python bindings for Apple's FoundationModels framework - Direct access to on-dev
|
|
|
24
25
|
pip install apple-foundation-models
|
|
25
26
|
```
|
|
26
27
|
|
|
28
|
+
**Optional dependencies:**
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# For Pydantic model support in structured outputs
|
|
32
|
+
pip install apple-foundation-models[pydantic]
|
|
33
|
+
```
|
|
34
|
+
|
|
27
35
|
### From Source
|
|
28
36
|
|
|
29
37
|
```bash
|
|
@@ -39,7 +47,7 @@ pip install -e .
|
|
|
39
47
|
|
|
40
48
|
- macOS 26.0+ (Sequoia) with Apple Intelligence enabled
|
|
41
49
|
- Xcode command line tools (`xcode-select --install`)
|
|
42
|
-
- Python 3.
|
|
50
|
+
- Python 3.9 or higher
|
|
43
51
|
|
|
44
52
|
**Note:** The Swift dylib is built automatically during installation.
|
|
45
53
|
|
|
@@ -117,9 +125,137 @@ with Client() as client:
|
|
|
117
125
|
schema=schema
|
|
118
126
|
)
|
|
119
127
|
|
|
120
|
-
print(result
|
|
128
|
+
print(result) # {'name': 'Alice', 'age': 28, 'city': 'Paris'}
|
|
121
129
|
```
|
|
122
130
|
|
|
131
|
+
#### Using Pydantic Models
|
|
132
|
+
|
|
133
|
+
You can also use Pydantic models for structured outputs (requires `pip install pydantic>=2.0`):
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from applefoundationmodels import Client
|
|
137
|
+
from pydantic import BaseModel
|
|
138
|
+
|
|
139
|
+
class Person(BaseModel):
|
|
140
|
+
name: str
|
|
141
|
+
age: int
|
|
142
|
+
city: str
|
|
143
|
+
|
|
144
|
+
with Client() as client:
|
|
145
|
+
session = client.create_session()
|
|
146
|
+
|
|
147
|
+
# Pass Pydantic model directly - no need for JSON schema!
|
|
148
|
+
result = session.generate_structured(
|
|
149
|
+
"Extract person info: Alice is 28 and lives in Paris",
|
|
150
|
+
schema=Person
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
print(result) # {'name': 'Alice', 'age': 28, 'city': 'Paris'}
|
|
154
|
+
|
|
155
|
+
# Parse directly into a Pydantic model for validation
|
|
156
|
+
person = Person(**result)
|
|
157
|
+
print(person.name, person.age, person.city) # Alice 28 Paris
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Tool Calling
|
|
161
|
+
|
|
162
|
+
Tool calling allows the model to call your Python functions to access real-time data, perform actions, or integrate with external systems. Tools work with a simple decorator-based API:
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
from applefoundationmodels import Client
|
|
166
|
+
|
|
167
|
+
with Client() as client:
|
|
168
|
+
session = client.create_session()
|
|
169
|
+
|
|
170
|
+
# Register a tool with the @session.tool decorator
|
|
171
|
+
@session.tool(description="Get current weather for a location")
|
|
172
|
+
def get_weather(location: str, units: str = "celsius") -> str:
|
|
173
|
+
"""Fetch weather information from your weather API."""
|
|
174
|
+
# Your implementation here
|
|
175
|
+
return f"Weather in {location}: 22°{units[0].upper()}, sunny"
|
|
176
|
+
|
|
177
|
+
@session.tool()
|
|
178
|
+
def calculate(expression: str) -> float:
|
|
179
|
+
"""Evaluate a mathematical expression safely."""
|
|
180
|
+
# Your implementation here
|
|
181
|
+
return eval(expression) # Use safe_eval in production!
|
|
182
|
+
|
|
183
|
+
# The model will automatically call tools when needed
|
|
184
|
+
response = session.generate(
|
|
185
|
+
"What's the weather in Paris and what's 15 times 23?"
|
|
186
|
+
)
|
|
187
|
+
print(response)
|
|
188
|
+
# "The weather in Paris is 22°C and sunny. 15 times 23 equals 345."
|
|
189
|
+
|
|
190
|
+
# View the full conversation including tool calls
|
|
191
|
+
for entry in session.transcript:
|
|
192
|
+
print(f"{entry['type']}: {entry.get('content', '')}")
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Features:**
|
|
196
|
+
- **Automatic schema generation** from Python type hints
|
|
197
|
+
- **Parallel tool execution** when the model calls multiple tools
|
|
198
|
+
- **Full transcript access** showing all tool calls and outputs
|
|
199
|
+
- **Error handling** with detailed error information
|
|
200
|
+
- **Type-safe** with complete type annotations
|
|
201
|
+
|
|
202
|
+
**Schema Extraction:**
|
|
203
|
+
|
|
204
|
+
The library automatically extracts JSON schemas from your Python functions:
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
@session.tool(description="Search documentation")
|
|
208
|
+
def search_docs(query: str, limit: int = 10, category: str = "all") -> list:
|
|
209
|
+
"""Search the documentation database."""
|
|
210
|
+
# Implementation...
|
|
211
|
+
return results
|
|
212
|
+
|
|
213
|
+
# Automatically generates:
|
|
214
|
+
# {
|
|
215
|
+
# "name": "search_docs",
|
|
216
|
+
# "description": "Search documentation",
|
|
217
|
+
# "parameters": {
|
|
218
|
+
# "type": "object",
|
|
219
|
+
# "properties": {
|
|
220
|
+
# "query": {"type": "string"},
|
|
221
|
+
# "limit": {"type": "integer"},
|
|
222
|
+
# "category": {"type": "string"}
|
|
223
|
+
# },
|
|
224
|
+
# "required": ["query"]
|
|
225
|
+
# }
|
|
226
|
+
# }
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Transcript Access:**
|
|
230
|
+
|
|
231
|
+
View the complete conversation history including tool interactions:
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
# After generating with tools
|
|
235
|
+
for entry in session.transcript:
|
|
236
|
+
match entry['type']:
|
|
237
|
+
case 'prompt':
|
|
238
|
+
print(f"User: {entry['content']}")
|
|
239
|
+
case 'tool_calls':
|
|
240
|
+
for call in entry['tool_calls']:
|
|
241
|
+
print(f"Calling tool: {call['id']}")
|
|
242
|
+
case 'tool_output':
|
|
243
|
+
print(f"Tool result: {entry['content']}")
|
|
244
|
+
case 'response':
|
|
245
|
+
print(f"Assistant: {entry['content']}")
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
**Supported Parameter Types:**
|
|
249
|
+
|
|
250
|
+
Tool calling works with various parameter signatures:
|
|
251
|
+
- No parameters
|
|
252
|
+
- Single parameters (string, int, float, bool)
|
|
253
|
+
- Multiple parameters with mixed types
|
|
254
|
+
- Optional parameters with default values
|
|
255
|
+
- Lists and nested objects
|
|
256
|
+
|
|
257
|
+
See `examples/tool_calling_comprehensive.py` for complete examples of all supported patterns.
|
|
258
|
+
|
|
123
259
|
### Generation Parameters
|
|
124
260
|
|
|
125
261
|
```python
|
|
@@ -217,6 +353,10 @@ class Session:
|
|
|
217
353
|
def generate_structured(prompt: str, schema: dict, **params) -> dict: ...
|
|
218
354
|
async def generate_stream(prompt: str, **params) -> AsyncIterator[str]: ...
|
|
219
355
|
|
|
356
|
+
def tool(description: str = None, name: str = None) -> Callable: ...
|
|
357
|
+
@property
|
|
358
|
+
def transcript() -> List[dict]: ...
|
|
359
|
+
|
|
220
360
|
def get_history() -> List[dict]: ...
|
|
221
361
|
def clear_history() -> None: ...
|
|
222
362
|
def add_message(role: str, content: str) -> None: ...
|
|
@@ -268,6 +408,7 @@ All exceptions inherit from `FoundationModelsError`:
|
|
|
268
408
|
- `GuardrailViolationError` - Content blocked by safety filters
|
|
269
409
|
- `ToolNotFoundError` - Tool not registered
|
|
270
410
|
- `ToolExecutionError` - Tool execution failed
|
|
411
|
+
- `ToolCallError` - Tool call error (validation, schema, etc.)
|
|
271
412
|
- `UnknownError` - Unknown error
|
|
272
413
|
|
|
273
414
|
## Examples
|
|
@@ -276,24 +417,41 @@ See the `examples/` directory for complete working examples:
|
|
|
276
417
|
|
|
277
418
|
- `basic_chat.py` - Simple conversation
|
|
278
419
|
- `streaming_chat.py` - Async streaming
|
|
279
|
-
- `tool_calling.py` - Tool registration (coming soon)
|
|
280
420
|
- `structured_output.py` - JSON schema validation
|
|
421
|
+
- `tool_calling_comprehensive.py` - Complete tool calling demonstration with all parameter types
|
|
281
422
|
|
|
282
423
|
## Development
|
|
283
424
|
|
|
284
425
|
### Building from Source
|
|
285
426
|
|
|
427
|
+
This project uses [uv](https://docs.astral.sh/uv/) for fast, reliable builds and dependency management:
|
|
428
|
+
|
|
286
429
|
```bash
|
|
430
|
+
# Install uv (if not already installed)
|
|
431
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
432
|
+
|
|
287
433
|
# Install development dependencies
|
|
288
|
-
|
|
434
|
+
uv sync --extra dev
|
|
289
435
|
|
|
290
436
|
# Run tests
|
|
291
|
-
pytest
|
|
437
|
+
uv run pytest
|
|
292
438
|
|
|
293
439
|
# Type checking
|
|
294
|
-
mypy applefoundationmodels
|
|
440
|
+
uv run mypy applefoundationmodels
|
|
295
441
|
|
|
296
442
|
# Format code
|
|
443
|
+
uv run black applefoundationmodels examples
|
|
444
|
+
|
|
445
|
+
# Build wheels
|
|
446
|
+
uv build --wheel
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
You can also use pip if preferred:
|
|
450
|
+
|
|
451
|
+
```bash
|
|
452
|
+
pip install -e ".[dev]"
|
|
453
|
+
pytest
|
|
454
|
+
mypy applefoundationmodels
|
|
297
455
|
black applefoundationmodels examples
|
|
298
456
|
```
|
|
299
457
|
|