optimizely-opal.opal-tools-sdk 0.1.10.dev0__tar.gz → 0.1.12.dev0__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.
- {optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/PKG-INFO +99 -6
- {optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/README.md +94 -5
- {optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/opal_tools_sdk/__init__.py +4 -0
- optimizely_opal_opal_tools_sdk-0.1.12.dev0/opal_tools_sdk/block.py +9985 -0
- {optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/opal_tools_sdk/decorators.py +16 -3
- {optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/opal_tools_sdk/models.py +8 -1
- {optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/opal_tools_sdk/service.py +23 -1
- {optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/optimizely_opal.opal_tools_sdk.egg-info/PKG-INFO +99 -6
- {optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/optimizely_opal.opal_tools_sdk.egg-info/SOURCES.txt +4 -1
- optimizely_opal_opal_tools_sdk-0.1.12.dev0/optimizely_opal.opal_tools_sdk.egg-info/requires.txt +8 -0
- {optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/pyproject.toml +10 -9
- {optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/setup.py +1 -1
- optimizely_opal_opal_tools_sdk-0.1.12.dev0/tests/test_block.py +105 -0
- optimizely_opal_opal_tools_sdk-0.1.12.dev0/tests/test_integration.py +181 -0
- optimizely_opal_opal_tools_sdk-0.1.10.dev0/optimizely_opal.opal_tools_sdk.egg-info/requires.txt +0 -3
- {optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/opal_tools_sdk/_registry.py +0 -0
- {optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/opal_tools_sdk/auth.py +0 -0
- {optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/opal_tools_sdk/logging.py +0 -0
- {optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/optimizely_opal.opal_tools_sdk.egg-info/dependency_links.txt +0 -0
- {optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/optimizely_opal.opal_tools_sdk.egg-info/top_level.txt +0 -0
- {optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/setup.cfg +0 -0
{optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: optimizely-opal.opal-tools-sdk
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.12.dev0
|
|
4
4
|
Summary: SDK for creating Opal-compatible tools services
|
|
5
5
|
Home-page: https://github.com/optimizely/opal-tools-sdk
|
|
6
6
|
Author: Optimizely
|
|
@@ -18,6 +18,10 @@ Description-Content-Type: text/markdown
|
|
|
18
18
|
Requires-Dist: fastapi>=0.100.0
|
|
19
19
|
Requires-Dist: pydantic>=2.0.0
|
|
20
20
|
Requires-Dist: httpx>=0.24.1
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: datamodel-code-generator>=0.25.0; extra == "dev"
|
|
23
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
24
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
21
25
|
Dynamic: author
|
|
22
26
|
Dynamic: home-page
|
|
23
27
|
Dynamic: requires-python
|
|
@@ -33,7 +37,8 @@ This SDK simplifies the creation of tools services compatible with the Opal Tool
|
|
|
33
37
|
- Parameter validation and type checking
|
|
34
38
|
- Authentication helpers
|
|
35
39
|
- FastAPI integration
|
|
36
|
-
-
|
|
40
|
+
- **Adaptive Blocks** for interactive forms and UI flows (new!)
|
|
41
|
+
- Island components for interactive UI responses (legacy)
|
|
37
42
|
|
|
38
43
|
## Installation
|
|
39
44
|
|
|
@@ -45,7 +50,7 @@ Note: While the package is installed as `optimizely-opal.opal-tools-sdk`, you'll
|
|
|
45
50
|
|
|
46
51
|
```python
|
|
47
52
|
# Import using the package name
|
|
48
|
-
from opal_tools_sdk import ToolsService, tool, IslandResponse, IslandConfig
|
|
53
|
+
from opal_tools_sdk import ToolsService, tool, Block, BlockResponse, IslandResponse, IslandConfig
|
|
49
54
|
```
|
|
50
55
|
|
|
51
56
|
## Usage
|
|
@@ -70,6 +75,65 @@ async def get_weather(parameters: WeatherParameters):
|
|
|
70
75
|
# Discovery endpoint is automatically created at /discovery
|
|
71
76
|
```
|
|
72
77
|
|
|
78
|
+
## Adaptive Blocks
|
|
79
|
+
|
|
80
|
+
Adaptive Blocks provide an interactive UI framework for tools to capture user input directly through forms, rather than having the LLM gather parameters through chat messages.
|
|
81
|
+
|
|
82
|
+
### Basic Example
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
from opal_tools_sdk import Block, BlockResponse, tool
|
|
86
|
+
from pydantic import BaseModel, Field
|
|
87
|
+
|
|
88
|
+
class MyToolParams(BaseModel):
|
|
89
|
+
user_input: str | None = Field(default=None, description="User input")
|
|
90
|
+
|
|
91
|
+
@tool(
|
|
92
|
+
name="my_tool",
|
|
93
|
+
description="Example tool with Block Document",
|
|
94
|
+
type="block" # Important: Specify type="block"
|
|
95
|
+
)
|
|
96
|
+
async def my_tool(params: MyToolParams) -> BlockResponse:
|
|
97
|
+
# If parameters are missing, show a form
|
|
98
|
+
if not params.user_input:
|
|
99
|
+
return BlockResponse(
|
|
100
|
+
content=Block.Document(
|
|
101
|
+
children=[
|
|
102
|
+
Block.Heading(children="Enter Details", level="2"),
|
|
103
|
+
Block.Field(
|
|
104
|
+
label="User Input",
|
|
105
|
+
required=True,
|
|
106
|
+
children=Block.Input(
|
|
107
|
+
name="user_input",
|
|
108
|
+
placeholder="Enter something..."
|
|
109
|
+
)
|
|
110
|
+
),
|
|
111
|
+
],
|
|
112
|
+
actions=[
|
|
113
|
+
Block.Action(name="submit", children="Submit"),
|
|
114
|
+
Block.CancelAction(children="Cancel")
|
|
115
|
+
],
|
|
116
|
+
blocking=True # Hide chat prompt, force form interaction
|
|
117
|
+
)
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
# Process the input and return as Block Document
|
|
121
|
+
return BlockResponse(
|
|
122
|
+
content=Block.Document(
|
|
123
|
+
children=[
|
|
124
|
+
Block.Heading(children="Result", level="2"),
|
|
125
|
+
Block.Text(children=f"You entered: {params.user_input}")
|
|
126
|
+
]
|
|
127
|
+
)
|
|
128
|
+
)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Important:** When using `type="block"`, the function MUST:
|
|
132
|
+
|
|
133
|
+
1. Have a return type annotation of `-> BlockResponse`
|
|
134
|
+
2. Always return a `BlockResponse` object (even for success/error cases)
|
|
135
|
+
3. Wrap all responses in `Block.Document()` for consistency
|
|
136
|
+
|
|
73
137
|
## Authentication
|
|
74
138
|
|
|
75
139
|
The SDK provides two ways to require authentication for your tools:
|
|
@@ -110,7 +174,7 @@ async def get_calendar_events(parameters: CalendarParameters, auth_data: Optiona
|
|
|
110
174
|
async def get_calendar_availability(parameters: CalendarParameters, auth_data: Optional[AuthData] = None):
|
|
111
175
|
provider = ""
|
|
112
176
|
token = ""
|
|
113
|
-
|
|
177
|
+
|
|
114
178
|
if auth_data:
|
|
115
179
|
provider = auth_data["provider"]
|
|
116
180
|
token = auth_data["credentials"]["access_token"]
|
|
@@ -162,7 +226,7 @@ class WeatherParameters(BaseModel):
|
|
|
162
226
|
async def get_weather(parameters: WeatherParameters):
|
|
163
227
|
# Get weather data (implementation details omitted)
|
|
164
228
|
weather_data = {"temperature": 22, "condition": "sunny", "humidity": 65}
|
|
165
|
-
|
|
229
|
+
|
|
166
230
|
# Create an interactive island for weather settings
|
|
167
231
|
island = IslandConfig(
|
|
168
232
|
fields=[
|
|
@@ -196,14 +260,16 @@ async def get_weather(parameters: WeatherParameters):
|
|
|
196
260
|
)
|
|
197
261
|
]
|
|
198
262
|
)
|
|
199
|
-
|
|
263
|
+
|
|
200
264
|
return IslandResponse.create([island])
|
|
201
265
|
```
|
|
202
266
|
|
|
203
267
|
### Island Components
|
|
204
268
|
|
|
205
269
|
#### IslandConfig.Field
|
|
270
|
+
|
|
206
271
|
Fields represent data inputs in the UI:
|
|
272
|
+
|
|
207
273
|
- `name`: Programmatic field identifier
|
|
208
274
|
- `label`: Human-readable label
|
|
209
275
|
- `type`: Field type (`"string"`, `"boolean"`, `"json"`)
|
|
@@ -212,7 +278,9 @@ Fields represent data inputs in the UI:
|
|
|
212
278
|
- `options`: Available options for selection (optional)
|
|
213
279
|
|
|
214
280
|
#### IslandConfig.Action
|
|
281
|
+
|
|
215
282
|
Actions represent buttons or operations:
|
|
283
|
+
|
|
216
284
|
- `name`: Programmatic action identifier
|
|
217
285
|
- `label`: Human-readable button label
|
|
218
286
|
- `type`: UI element type (typically `"button"`)
|
|
@@ -220,14 +288,18 @@ Actions represent buttons or operations:
|
|
|
220
288
|
- `operation`: Operation type (default: `"create"`)
|
|
221
289
|
|
|
222
290
|
#### IslandConfig
|
|
291
|
+
|
|
223
292
|
Contains the complete island configuration:
|
|
293
|
+
|
|
224
294
|
- `fields`: List of IslandConfig.Field objects
|
|
225
295
|
- `actions`: List of IslandConfig.Action objects
|
|
226
296
|
- `type`: Island type for UI rendering (optional, default: `None`)
|
|
227
297
|
- `icon`: Icon to display in the island (optional, default: `None`)
|
|
228
298
|
|
|
229
299
|
#### IslandResponse
|
|
300
|
+
|
|
230
301
|
The response wrapper for islands:
|
|
302
|
+
|
|
231
303
|
- Use `IslandResponse.create([islands])` to create responses
|
|
232
304
|
- Supports multiple islands per response
|
|
233
305
|
|
|
@@ -236,20 +308,41 @@ The response wrapper for islands:
|
|
|
236
308
|
The SDK provides several TypedDict and dataclass definitions for better type safety:
|
|
237
309
|
|
|
238
310
|
### Authentication Types
|
|
311
|
+
|
|
239
312
|
- `AuthData`: TypedDict containing provider and credentials information
|
|
240
313
|
- `Credentials`: TypedDict with access_token, org_sso_id, customer_id, instance_id, and product_sku
|
|
241
314
|
- `AuthRequirement`: Dataclass for specifying authentication requirements
|
|
242
315
|
|
|
243
316
|
### Execution Environment
|
|
317
|
+
|
|
244
318
|
- `Environment`: TypedDict specifying execution mode (`"headless"` or `"interactive"`)
|
|
245
319
|
|
|
246
320
|
### Parameter Types
|
|
321
|
+
|
|
247
322
|
- `ParameterType`: Enum for supported parameter types (string, integer, number, boolean, list, dictionary)
|
|
248
323
|
- `Parameter`: Dataclass for tool parameter definitions
|
|
249
324
|
- `Function`: Dataclass for complete tool function definitions
|
|
250
325
|
|
|
251
326
|
These types are automatically imported when you import from `opal_tools_sdk` and provide better IDE support and type checking.
|
|
252
327
|
|
|
328
|
+
## Code Generation
|
|
329
|
+
|
|
330
|
+
The Block Document types is automatically generated from the JSON schema for full type safety and Pydantic validation.
|
|
331
|
+
|
|
332
|
+
### Generating Types
|
|
333
|
+
|
|
334
|
+
To use the code generation:
|
|
335
|
+
|
|
336
|
+
```bash
|
|
337
|
+
# Install dev dependencies
|
|
338
|
+
pip install -e ".[dev]"
|
|
339
|
+
|
|
340
|
+
# Generate types from schema
|
|
341
|
+
make generate-block
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
This generates Pydantic v2 models from `block-document-spec.json` to `opal_tools_sdk/block.py` with builder methods included.
|
|
345
|
+
|
|
253
346
|
## Documentation
|
|
254
347
|
|
|
255
348
|
See full documentation for more examples and configuration options.
|
{optimizely_opal_opal_tools_sdk-0.1.10.dev0 → optimizely_opal_opal_tools_sdk-0.1.12.dev0}/README.md
RENAMED
|
@@ -9,7 +9,8 @@ This SDK simplifies the creation of tools services compatible with the Opal Tool
|
|
|
9
9
|
- Parameter validation and type checking
|
|
10
10
|
- Authentication helpers
|
|
11
11
|
- FastAPI integration
|
|
12
|
-
-
|
|
12
|
+
- **Adaptive Blocks** for interactive forms and UI flows (new!)
|
|
13
|
+
- Island components for interactive UI responses (legacy)
|
|
13
14
|
|
|
14
15
|
## Installation
|
|
15
16
|
|
|
@@ -21,7 +22,7 @@ Note: While the package is installed as `optimizely-opal.opal-tools-sdk`, you'll
|
|
|
21
22
|
|
|
22
23
|
```python
|
|
23
24
|
# Import using the package name
|
|
24
|
-
from opal_tools_sdk import ToolsService, tool, IslandResponse, IslandConfig
|
|
25
|
+
from opal_tools_sdk import ToolsService, tool, Block, BlockResponse, IslandResponse, IslandConfig
|
|
25
26
|
```
|
|
26
27
|
|
|
27
28
|
## Usage
|
|
@@ -46,6 +47,65 @@ async def get_weather(parameters: WeatherParameters):
|
|
|
46
47
|
# Discovery endpoint is automatically created at /discovery
|
|
47
48
|
```
|
|
48
49
|
|
|
50
|
+
## Adaptive Blocks
|
|
51
|
+
|
|
52
|
+
Adaptive Blocks provide an interactive UI framework for tools to capture user input directly through forms, rather than having the LLM gather parameters through chat messages.
|
|
53
|
+
|
|
54
|
+
### Basic Example
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from opal_tools_sdk import Block, BlockResponse, tool
|
|
58
|
+
from pydantic import BaseModel, Field
|
|
59
|
+
|
|
60
|
+
class MyToolParams(BaseModel):
|
|
61
|
+
user_input: str | None = Field(default=None, description="User input")
|
|
62
|
+
|
|
63
|
+
@tool(
|
|
64
|
+
name="my_tool",
|
|
65
|
+
description="Example tool with Block Document",
|
|
66
|
+
type="block" # Important: Specify type="block"
|
|
67
|
+
)
|
|
68
|
+
async def my_tool(params: MyToolParams) -> BlockResponse:
|
|
69
|
+
# If parameters are missing, show a form
|
|
70
|
+
if not params.user_input:
|
|
71
|
+
return BlockResponse(
|
|
72
|
+
content=Block.Document(
|
|
73
|
+
children=[
|
|
74
|
+
Block.Heading(children="Enter Details", level="2"),
|
|
75
|
+
Block.Field(
|
|
76
|
+
label="User Input",
|
|
77
|
+
required=True,
|
|
78
|
+
children=Block.Input(
|
|
79
|
+
name="user_input",
|
|
80
|
+
placeholder="Enter something..."
|
|
81
|
+
)
|
|
82
|
+
),
|
|
83
|
+
],
|
|
84
|
+
actions=[
|
|
85
|
+
Block.Action(name="submit", children="Submit"),
|
|
86
|
+
Block.CancelAction(children="Cancel")
|
|
87
|
+
],
|
|
88
|
+
blocking=True # Hide chat prompt, force form interaction
|
|
89
|
+
)
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
# Process the input and return as Block Document
|
|
93
|
+
return BlockResponse(
|
|
94
|
+
content=Block.Document(
|
|
95
|
+
children=[
|
|
96
|
+
Block.Heading(children="Result", level="2"),
|
|
97
|
+
Block.Text(children=f"You entered: {params.user_input}")
|
|
98
|
+
]
|
|
99
|
+
)
|
|
100
|
+
)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Important:** When using `type="block"`, the function MUST:
|
|
104
|
+
|
|
105
|
+
1. Have a return type annotation of `-> BlockResponse`
|
|
106
|
+
2. Always return a `BlockResponse` object (even for success/error cases)
|
|
107
|
+
3. Wrap all responses in `Block.Document()` for consistency
|
|
108
|
+
|
|
49
109
|
## Authentication
|
|
50
110
|
|
|
51
111
|
The SDK provides two ways to require authentication for your tools:
|
|
@@ -86,7 +146,7 @@ async def get_calendar_events(parameters: CalendarParameters, auth_data: Optiona
|
|
|
86
146
|
async def get_calendar_availability(parameters: CalendarParameters, auth_data: Optional[AuthData] = None):
|
|
87
147
|
provider = ""
|
|
88
148
|
token = ""
|
|
89
|
-
|
|
149
|
+
|
|
90
150
|
if auth_data:
|
|
91
151
|
provider = auth_data["provider"]
|
|
92
152
|
token = auth_data["credentials"]["access_token"]
|
|
@@ -138,7 +198,7 @@ class WeatherParameters(BaseModel):
|
|
|
138
198
|
async def get_weather(parameters: WeatherParameters):
|
|
139
199
|
# Get weather data (implementation details omitted)
|
|
140
200
|
weather_data = {"temperature": 22, "condition": "sunny", "humidity": 65}
|
|
141
|
-
|
|
201
|
+
|
|
142
202
|
# Create an interactive island for weather settings
|
|
143
203
|
island = IslandConfig(
|
|
144
204
|
fields=[
|
|
@@ -172,14 +232,16 @@ async def get_weather(parameters: WeatherParameters):
|
|
|
172
232
|
)
|
|
173
233
|
]
|
|
174
234
|
)
|
|
175
|
-
|
|
235
|
+
|
|
176
236
|
return IslandResponse.create([island])
|
|
177
237
|
```
|
|
178
238
|
|
|
179
239
|
### Island Components
|
|
180
240
|
|
|
181
241
|
#### IslandConfig.Field
|
|
242
|
+
|
|
182
243
|
Fields represent data inputs in the UI:
|
|
244
|
+
|
|
183
245
|
- `name`: Programmatic field identifier
|
|
184
246
|
- `label`: Human-readable label
|
|
185
247
|
- `type`: Field type (`"string"`, `"boolean"`, `"json"`)
|
|
@@ -188,7 +250,9 @@ Fields represent data inputs in the UI:
|
|
|
188
250
|
- `options`: Available options for selection (optional)
|
|
189
251
|
|
|
190
252
|
#### IslandConfig.Action
|
|
253
|
+
|
|
191
254
|
Actions represent buttons or operations:
|
|
255
|
+
|
|
192
256
|
- `name`: Programmatic action identifier
|
|
193
257
|
- `label`: Human-readable button label
|
|
194
258
|
- `type`: UI element type (typically `"button"`)
|
|
@@ -196,14 +260,18 @@ Actions represent buttons or operations:
|
|
|
196
260
|
- `operation`: Operation type (default: `"create"`)
|
|
197
261
|
|
|
198
262
|
#### IslandConfig
|
|
263
|
+
|
|
199
264
|
Contains the complete island configuration:
|
|
265
|
+
|
|
200
266
|
- `fields`: List of IslandConfig.Field objects
|
|
201
267
|
- `actions`: List of IslandConfig.Action objects
|
|
202
268
|
- `type`: Island type for UI rendering (optional, default: `None`)
|
|
203
269
|
- `icon`: Icon to display in the island (optional, default: `None`)
|
|
204
270
|
|
|
205
271
|
#### IslandResponse
|
|
272
|
+
|
|
206
273
|
The response wrapper for islands:
|
|
274
|
+
|
|
207
275
|
- Use `IslandResponse.create([islands])` to create responses
|
|
208
276
|
- Supports multiple islands per response
|
|
209
277
|
|
|
@@ -212,20 +280,41 @@ The response wrapper for islands:
|
|
|
212
280
|
The SDK provides several TypedDict and dataclass definitions for better type safety:
|
|
213
281
|
|
|
214
282
|
### Authentication Types
|
|
283
|
+
|
|
215
284
|
- `AuthData`: TypedDict containing provider and credentials information
|
|
216
285
|
- `Credentials`: TypedDict with access_token, org_sso_id, customer_id, instance_id, and product_sku
|
|
217
286
|
- `AuthRequirement`: Dataclass for specifying authentication requirements
|
|
218
287
|
|
|
219
288
|
### Execution Environment
|
|
289
|
+
|
|
220
290
|
- `Environment`: TypedDict specifying execution mode (`"headless"` or `"interactive"`)
|
|
221
291
|
|
|
222
292
|
### Parameter Types
|
|
293
|
+
|
|
223
294
|
- `ParameterType`: Enum for supported parameter types (string, integer, number, boolean, list, dictionary)
|
|
224
295
|
- `Parameter`: Dataclass for tool parameter definitions
|
|
225
296
|
- `Function`: Dataclass for complete tool function definitions
|
|
226
297
|
|
|
227
298
|
These types are automatically imported when you import from `opal_tools_sdk` and provide better IDE support and type checking.
|
|
228
299
|
|
|
300
|
+
## Code Generation
|
|
301
|
+
|
|
302
|
+
The Block Document types is automatically generated from the JSON schema for full type safety and Pydantic validation.
|
|
303
|
+
|
|
304
|
+
### Generating Types
|
|
305
|
+
|
|
306
|
+
To use the code generation:
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
# Install dev dependencies
|
|
310
|
+
pip install -e ".[dev]"
|
|
311
|
+
|
|
312
|
+
# Generate types from schema
|
|
313
|
+
make generate-block
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
This generates Pydantic v2 models from `block-document-spec.json` to `opal_tools_sdk/block.py` with builder methods included.
|
|
317
|
+
|
|
229
318
|
## Documentation
|
|
230
319
|
|
|
231
320
|
See full documentation for more examples and configuration options.
|
|
@@ -3,6 +3,7 @@ from .decorators import tool
|
|
|
3
3
|
from .auth import requires_auth
|
|
4
4
|
from .logging import register_logger_factory
|
|
5
5
|
from .models import AuthData, AuthRequirement, Credentials, Environment, IslandConfig, IslandResponse
|
|
6
|
+
from .block import Block, BlockResponse
|
|
6
7
|
|
|
7
8
|
__version__ = "0.1.0"
|
|
8
9
|
__all__ = [
|
|
@@ -17,4 +18,7 @@ __all__ = [
|
|
|
17
18
|
"Environment",
|
|
18
19
|
"IslandConfig",
|
|
19
20
|
"IslandResponse",
|
|
21
|
+
# Block
|
|
22
|
+
"Block",
|
|
23
|
+
"BlockResponse",
|
|
20
24
|
]
|