-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathplugin-development.mdc
More file actions
342 lines (240 loc) · 7.86 KB
/
plugin-development.mdc
File metadata and controls
342 lines (240 loc) · 7.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
---
description: Guidelines for developing ado plugins (actuators, operators, custom_experiments)
globs: "{plugins,examples}/**/*"
alwaysApply: false
---
# Plugin Development Guidelines
These guidelines apply when developing plugins for ado.
Plugins are developed under `plugins/` or `examples/` directories.
All general development guidelines from `AGENTS.md` also apply.
---
## Plugin Structure
### Package Organization
- **Actuators**: Each actuator is its own package under `plugins/actuators/`
- **Operators**: Each operator is its own package under `plugins/operators/`
- **Custom Experiments**: Can have multiple custom experiments in a single package under `plugins/custom_experiments/`
### Directory Layout
Each plugin package should contain:
- `pyproject.toml` - Package configuration
- `tests/` - Unit and integration tests (keep within the plugin package)
- YAML examples - Example discoveryspace and operation files for the plugin
- Plugin implementation code
---
## Package Setup
### Using setuptools_scm for Versioning
Configure `pyproject.toml` to use `setuptools_scm` for automatic versioning:
```toml
[build-system]
requires = ["setuptools", "setuptools_scm"]
build-backend = "setuptools.build_meta"
[tool.setuptools_scm]
root = "../../../" # Points to repo root
[project]
name = "your-plugin-name"
dynamic = ["version"] # Version set automatically by setuptools_scm
```
### Dependencies
**Always include ado-core** in the dependencies:
```toml
[project]
dependencies = [
"ado-core",
# ... other dependencies
]
```
### Installation
Install the plugin into the top-level venv from the repo root:
```bash
uv pip install -e plugins/your_plugin_type/your_plugin
```
### Workspace Membership
By default, plugins added in-tree are not workspace members and should
not be added to `[tool.uv.workspace]` members in the root `pyproject.toml`.
This means the plugins pyproject.toml should not include a `[tool.uv.sources]`
section resolving `ado-core` via `{ workspace = true }`.
Only add a plugin to the workspace when explicitly
asked, for example when the plugin must be included in `uv sync` for CI or
cross-plugin dependency resolution.
If you mistakenly add `ado-core = { workspace = true }` to a plugin's
`[tool.uv.sources]` without adding it to the workspace, `uv pip install`
will fail with:
```
Failed to parse entry: `ado-core`
`ado-core` references a workspace ... but is not a workspace member
```
### Adding Dependencies with uv
Use `uv` to add new dependencies to your plugin:
```bash
cd plugins/actuators/your_plugin/
uv add package-name
```
---
## Plugin Registration
### Actuators: Namespaced Packages
Actuators use namespaced packages and require:
1. Package structure under a namespace
2. `actuator_definitions.yaml` file
3. Optional `experiments.yaml` file
```toml
[tool.setuptools.package-data]
your_actuator = [
"actuator_definitions.yaml", # Required
"experiments.yaml" # Optional
]
```
### Operators and Custom Experiments: Entry Points
Operators and custom experiments use entry points in `pyproject.toml`:
**Operator Example:**
```toml
[project.entry-points."ado.operators"]
ado-ray-tune = "ado_ray_tune.operator_function"
```
**Custom Experiment Example:**
```toml
[project.entry-points."ado.custom_experiments"]
min_gpu_experiment = "autoconf.min_gpu_recommender"
```
---
## Custom Experiments
### Decorator Requirements
Custom experiments **must** use the `@custom_experiment` decorator correctly:
```python
from typing import Any
from orchestrator.modules.actuators.custom_experiments import custom_experiment
from orchestrator.schema.property import ConstitutiveProperty
# Define your properties explicitly (or let ado infer from type annotations)
MyProperty = ConstitutiveProperty(...)
@custom_experiment(
required_properties=[MyProperty, ...],
optional_properties=[...],
output_property_identifiers=["output1", "output2"],
metadata={
"description": "Clear description of what this experiment does"
},
parameterization={},
)
def my_custom_experiment(my_property: float, ...) -> dict[str, Any]:
# Function parameters must match required/optional property identifiers
return {"output1": ..., "output2": ...}
```
**Key Points:**
- Function **parameter names must match the property identifiers** — ado maps
values to the function by name, not by position
- Positional parameters become required properties; keyword parameters become
optional properties
- Type annotations on positional parameters allow ado to infer domains:
`float` → continuous, `int` → discrete, `Literal` → categorical
- Return a `dict` whose keys include the `output_property_identifiers`
- Define `output_property_identifiers` for measurement results
- Include descriptive metadata
For the full decorator API and worked examples, see
[creating-custom-experiments.md](../../../website/docs/actuators/creating-custom-experiments.md).
---
## Testing Requirements
### Unit & Integration Test Location
Keep unit and integration tests **within the plugin package**,
not in the top-level `tests/` directory.
### Testing Checklist
Before considering a plugin complete, verify:
- **Plugin Installation**: Install the plugin into the top-level uv venv
from the repo root:
```bash
uv pip install -e plugins/your_plugin_type/your_plugin
```
- **Confirm actuator or operator registration**:
Run
```
uv run ado get actuators --details
```
or
```
uv run ado get operators
```
and confirm the plugin is installed
- **Experiment execution**: Use the `run_experiment` tool to verify custom_experiment or actuator experiments can execute successfully
For example:
```
uv run run_experiment point.yaml
```
- **Valid DiscoverySpace YAML**: Create and validate a discoveryspace YAML that uses the experiment/actuator
```bash
ado create discoveryspace -f space.yaml --dry-run
```
- **Valid Operation YAML**: Create and validate an operation YAML that uses the operator
```bash
ado create operation -f operation.yaml --dry-run
```
- **Unit tests pass**: Run pytest on the plugin package
```bash
uv run pytest plugins/your_plugin_type/your_plugin/tests/
```
### Example YAML Files
Include example YAML files in your plugin package that demonstrate:
- How to configure a discoveryspace with your actuator/experiment
- How to configure an operation with your operator
- Different use cases or configurations
---
## Linting
After making changes to plugin code, run linting at the plugin directory level:
```bash
cd plugins/actuators/your_plugin/
uv run black .
uv run ruff check --fix .
uv run tombi fmt .
```
Fix any issues that ruff cannot automatically resolve.
---
## Complete pyproject.toml Examples
### Actuator Example
```toml
[build-system]
requires = ["setuptools", "setuptools_scm"]
build-backend = "setuptools.build_meta"
[tool.setuptools_scm]
root = "../../../"
[tool.setuptools.packages.find]
where = ["."]
exclude = ["build", "build.*", "examples"]
[tool.setuptools.package-data]
my_actuator = ["actuator_definitions.yaml", "experiments.yaml"]
[project]
name = "my-actuator"
description = "Description of your actuator"
dynamic = ["version"]
dependencies = [
"ado-core",
]
```
### Operator Example
```toml
[build-system]
requires = ["setuptools", "setuptools_scm"]
build-backend = "setuptools.build_meta"
[tool.setuptools_scm]
root = "../../../"
[project]
name = "my-operator"
dynamic = ["version"]
dependencies = [
"ado-core",
]
[project.entry-points."ado.operators"]
my-operator = "my_operator.operator_function"
```
### Custom Experiment Example
```toml
[project]
name = "my-custom-experiment"
description = "Description of your custom experiment"
dynamic = ["version"]
dependencies = [
"ado-core",
]
[project.entry-points."ado.custom_experiments"]
my_experiment = "my_package.my_experiment"
[build-system]
requires = ["setuptools", "setuptools_scm"]
build-backend = "setuptools.build_meta"
[tool.setuptools_scm]
root = "../../../"
```